Question

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?

Was it helpful?

Solution

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.

OTHER TIPS

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.

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top