2015-07-04 40 views
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); 

为什么是这样呢?

回答

22

因为它是未定义的行为:[expr.shift]

的行为是不确定如果将右操作数是负的,或者大于或等于在推动左操作数的位长度。

至于具体不确定的行为,我想这是如下:

  • 随着-O0,它编译成实际执行的机器代码右移,并在某些机器(例如I相信x86是这样的),移位功能仅在移位32位字时才查看移位量的低5位;移位32与移位0相同。
  • 对于-O3,编译器自己计算常量,并将0放入程序中,而不是进行计算。

您可以检查程序集输出以查看我的预测是否正确。

+0

我期待第二种行为,但是在我的代码中,这取决于这种行为并且使用-O3标志编译,我确实有32个移位的非零结果。也许是因为编译器不一致地执行-O3优化。所以,在一天结束的时候,你不能依赖这个。如你所说,它是不确定的。 –

+0

PS:但我认为这是不对的,应该定义:来自左侧的位应该是零。期。 - –

相关问题