【发布时间】:2013-10-28 13:49:27
【问题描述】:
我一定是疯了,但我机器上的gcc 4.7.3 给出了最荒谬的结果。这是我正在测试的确切代码:
#include <iostream>
using namespace std;
int main(){
unsigned int b = 100000;
cout << (b>>b) << endl;
b = b >> b;
cout << b << endl;
b >>= b;
cout << b << endl;
return 0;
}
现在,任何自行右移的数字都应该得到 0(n/(2^n) == 0 带有 整数除法、n>1 和 正/无符号),但不知何故这是我的输出:
100000
100000
100000
我疯了吗?可能发生了什么?
【问题讨论】:
-
@ShafikYaghmour:这假设编译器甚至会费心输入指令。拒绝这个计划是完全有权利的。
-
@MSalters 确实,此时我们正在进入特定于编译器/平台/版本的内容,但对于当前和最近的版本,情况就是如此,正如我已经说过的那样,它是未定义的,所以你显然是靠自己的,
gcc似乎只在使用-O0时产生shr。 -
@ShafikYaghmour:英特尔只是 gcc 支持的众多平台之一,它们有不同的优化阶段。优化中的一个常见技巧是说“这个值只能在 0 和 31 之间,因为它用于移位,如果我按照代码路径 X 到达这里,值不会介于 0 和 31 之间,所以代码路径 X 是不可能的而且我什至不需要为它生成指令”。众所周知,GCC 会为空指针检查执行此操作。
-
@MSalters 有道理,所以这也会影响警告?
-
一个有趣的事实:虽然这是 C 中的 undefined 行为,但它是 C# 中的 defined 行为,但定义有些奇怪。在 C# 中,32 位整数 x 和 y 的
x>>y计算为x>>(y&0x1f)!所以(x >> 16) >> 16是零,但x >> 32是x。
标签: c++ gcc undefined-behavior bit-shift