理解2 ^ 31和-2 ^ 31整数提升

时间:2016-02-01 12:45:17

标签: c++ c implicit-conversion 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;
}

C和C ++中的此代码,cygwin64和带有gcc 5.2.0的rhel6.4机器的输出是:

sizeof(int): 4
1
0
1
0

根据“Integer promotions”,2147483648u类型为unsigned int(即使没有u后缀),-2147483648类型为int } (照常)。为什么显式铸造的结果不同?

根据“Usual arithmetic conversions”,本段适用:

  

否则,签名是不同的:如果操作数与   无符号类型的转换等级大于或等于等级   签名操作数的类型,然后是带有签名类型的操作数   隐式转换为无符号类型

这意味着正确的结果就像:

2147483648u > 2147483648u
2147483648u != 2147483648u
执行

,因为在32位中,带符号-2 ^ 31和无符号2 ^ 31具有相同的表示。换句话说,铸造的结果是正确的。发生了什么事?

我感觉不知何故,在没有强制转换的情况下应用更高级别的整数提升,所以我得到了双方签署64位促销 - 但为什么?

这两个可执行文件都编译为64位,这可以发挥作用吗?

1 个答案:

答案 0 :(得分:12)

没有负整数常量。应用了一元-运算符只有正数。

2147483648 > INT_MAX以来,2147483648u提升为下一个更大的已签名(因为您没有附加-)整数类型,之前 {{1}应用。

顺便说一句,这就是INT_MIN通常在(-INT_MAX - 1)中定义为<limits.h>的原因。 ; - )