为什么"int>> 32`并不总是为零吗? [英] Why is `int >> 32` not always zero?
问题描述
有人可以解释一下为什么在C/C ++中对某个4字节整数进行右32位按位移位可能不会返回零吗?为什么它取决于编译器的-O
选项?
Can someone explain me why right 32 bitwise shift of some 4 byte integer number may return not zero in C/C++ ? Why does it depend on -O
option of the compiler?
例如,这段代码在gcc 4.8.3中为-O0
提供了45个,为-O3
提供了0:
For example this code gives 45 with -O0
and 0 with -O3
options in gcc 4.8.3:
unsigned int x = 45; // 4 bytes
x = x >> 32;
printf("%u\n", x);
为什么会这样?
推荐答案
因为它是未定义的行为,所以:[expr.shift]
说
Because it is undefined behavior: [expr.shift]
says
如果右操作数为负或大于或等于提升后的左操作数的位长度,则该行为是不确定的.
The behavior is undefined if the right operand is negative, or greater than or equal to the length in bits of the promoted left operand.
对于特定的未定义行为,我想它是这样的:
As for the specific undefined behavior, I imagine it is as follows:
- 使用
-O0
,它可以编译为实际执行机器代码的右移,并且在某些机器上(例如,我相信x86就是这样),当将32移位32时,移位函数仅查看移位量的低5位.位字;移32等于移0. - 使用
-O3
,编译器自己计算常量,然后将0
放入程序中,而不是让它进行计算.
- With
-O0
, it compiled to actually perform a right shift in machine code, and on some machines (e.g. I believe x86 is such), shift functions only look at the low 5 bits of the shift amount when shifting a 32-bit word; shifting by 32 is the same as shifting by 0. - With
-O3
, the compiler computed the constant itself, and just put0
into the program rather than having it do a calculation.
您可以检查程序集的输出以查看我的预测是否正确.
You can check the assembly output to see if my prediction is right.
这篇关于为什么"int>> 32`并不总是为零吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!