3
有人可以解释一下为什么在C/C++中为什么某些4字节整数的右边32位按位移可能返回不为零?为什么它取决于编译器的-O
选项?为什么`int >> 32`不总是为零?
例如该代码给出了45 -O0
和0与-O3
选项GCC 4.8.3:
unsigned int x = 45; // 4 bytes
x = x >> 32;
printf("%u\n", x);
为什么是这样呢?
有人可以解释一下为什么在C/C++中为什么某些4字节整数的右边32位按位移可能返回不为零?为什么它取决于编译器的-O
选项?为什么`int >> 32`不总是为零?
例如该代码给出了45 -O0
和0与-O3
选项GCC 4.8.3:
unsigned int x = 45; // 4 bytes
x = x >> 32;
printf("%u\n", x);
为什么是这样呢?
因为它是未定义的行为:[expr.shift]
说
的行为是不确定如果将右操作数是负的,或者大于或等于在推动左操作数的位长度。
至于具体不确定的行为,我想这是如下:
-O0
,它编译成实际执行的机器代码右移,并在某些机器(例如I相信x86是这样的),移位功能仅在移位32位字时才查看移位量的低5位;移位32与移位0相同。-O3
,编译器自己计算常量,并将0
放入程序中,而不是进行计算。您可以检查程序集输出以查看我的预测是否正确。
我期待第二种行为,但是在我的代码中,这取决于这种行为并且使用-O3标志编译,我确实有32个移位的非零结果。也许是因为编译器不一致地执行-O3优化。所以,在一天结束的时候,你不能依赖这个。如你所说,它是不确定的。 –
PS:但我认为这是不对的,应该定义:来自左侧的位应该是零。期。 - –