Reputation: 13407
This code prints B2
short a=-5;
unsigned short b=-5u;
if(a==b)
printf("A1");
else
printf("B2");
I read about integer promotion but it's still unclear to me, how does it work in the example here? Can someone thoroughly post the steps the compiler follows in widening/truncating the values?
Upvotes: 8
Views: 4564
Reputation: 46249
Let's walk through your code:
short a = -5;
a = -5, which fits into a short. So far so easy.
unsigned short b = -5u;
-5u means apply the unary -
operator to the constant 5u. 5u is (unsigned int) 5, and the unary -
does no promotion, so you end up with 4294967291 which is 2^32-5. (Update: I got this bit wrong in my original answer; see a test script which shows this version is correct here http://codepad.org/hjooaQFW)
Now when putting that in b, it is truncated to an unsigned short (2 bytes, usually), so b = 65531, which is 2^16-5.
if( a == b )
In this line, a and b are both promoted to ints so that the comparison can happen correctly. If they were promoted to shorts, b would potentially wrap around. If they were promoted to unsigned shorts, a would potentially wrap around.
So it's like saying if( (int) a == (int) b )
. And a = -5, so (int) a = -5, and b = 65531, so (int) b = 65531, because ints are bigger than shorts.
Upvotes: 11
Reputation: 145829
a == b
a
and b
are both promoted to int
in the above expression.
unsigned short b=-5u;
In this declaration -5U
is converted to unsigned short
by the means of integer conversion (C99, 6.3.1.3p2 applies here) and becomes a large value.
(C99, 6.3.1.3p2) "Otherwise, if the new type is unsigned, the value is converted by repeatedly adding or subtracting one more than the maximum value that can be represented in the new type until the value is in the range of the new type."
b
value is then (unsigned short) ((unsigned int) USHRT_MAX + 1 -5)
which is (unsigned short) 65531
if USHRT_MAX
is (unsigned short) 65535
.
So what you have is:
(short) -5 == (unsigned short) 65531
which is equivalent after integer promotion of both operands to:
-5 == 65531
which is equivalent to 0
.
Upvotes: 2
Reputation:
short
to unsigned short
is a conversion (thus having conversion rank)
short
to int
is a promotion (thus having promotion rank)
Promotions are preferred over conversions because of the ranking. Promotions occur during arithmetic and other operations. Conversions occur when merely storing one integral type inside another. Arithmetic ops can cause conversions as well as promotions, in order to coerce the types together. For another example:
unsigned int u = 2;
int i = 2;
u + i;
i
is converted (not promoted) to unsigned
.
Your value is converted to a larger value because it wraps around due to being unsigned
. Then, they are promoted to int
. Thus a != b
because of this.
Upvotes: 1