Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Understanding 2^31 and -2^31 integer promotion

#include <stdio.h>

int main() {
    printf("sizeof(int): %zu\n", sizeof(int));
    printf("%d\n", 2147483648u > -2147483648);
    printf("%d\n", ((unsigned int)2147483648u) > ((int)-2147483648));
    printf("%d\n", 2147483648u != -2147483648);
    printf("%d\n", ((unsigned int)2147483648u) != ((int)-2147483648));
    return 0;
}

The output of this code in both C and C++, on cygwin64 and an rhel6.4 machine with gcc 5.2.0 is:

sizeof(int): 4
1
0
1
0

According to "Integer promotions", 2147483648u will be of type unsigned int (even without the u suffix) and -2147483648 of type int (as usual). Why the different results with explicit casting?

According to the "Usual arithmetic conversions", this paragraph applies:

Otherwise, the signedness is different: If the operand with the unsigned type has conversion rank greater or equal than the rank of the type of the signed operand, then the operand with the signed type is implicitly converted to the unsigned type

This means that the correct result is as if:

2147483648u > 2147483648u
2147483648u != 2147483648u

were performed, because in 32 bits, signed -2^31 and unsigned 2^31 have the same representation. In other words, the result with casting is correct. What is going on?

I have the feeling that somehow, a higher-rank integer promotion is applied without casting, so I'm getting e.g. a 64-bit signed promotion on both sides -- but why?

Both executables are compiled as 64-bit, can this play a role?

like image 781
Irfy Avatar asked Feb 01 '16 12:02

Irfy


1 Answers

There are no negative integer constants. There are only positive ones with the unary - operator applied.

Since 2147483648 > INT_MAX, that promotes 2147483648 to the next larger signed (because you did not append u) integer type, before the - is applied.


By the way, that is why INT_MIN is usually defined as (-INT_MAX - 1) in <limits.h>. ;-)

like image 200
DevSolar Avatar answered Sep 23 '22 05:09

DevSolar