代码如下所示。我在VS,clang ++和G ++上测试过它。所有这些都表明1 << 32
和1 << i
(其中我是32)是不同的。我看了一下组装。看起来编译器在编译时计算1 << 32
的结果。我认为这种不一致应该是一个错误,或者它只是C ++的另一个未定义的行为。
#include <iostream>
int main(int argc, char *argv[])
{
std::cout << (1 << 32) << std::endl;
int i = 32;
std::cout << (1 << i) << std::endl;
return 0;
}
结果:
clang++:
1 << 32:73832
1 << i:1
g++:
1 << 32:73832
1 << i:1
答案 0 :(得分:8)
std :: cout&lt;&lt; (1 <&lt; 32)&lt;&lt;的std :: ENDL;
如果int
是您系统上的4个字节,则为undefined behavior。从标准(关于移位运算符的部分):
结果的类型是提升的左操作数的类型。该 如果右操作数为负数,或更高,则行为未定义 大于或等于提升的左操作数的位数。
答案 1 :(得分:3)
C ++标准说
E1 << E2
的值为E1
左移E2
位位置;空位是零填充的。如果E1
具有unsigned
类型,则结果的值为E1×2^E2
,比结果类型中可表示的最大值减少一个模数。否则,如果E1
具有signed
类型且非负值,并且E1×2^E2
在结果类型中可表示,那么这就是结果值; 否则,行为未定义。
然后
结果的类型是提升的左操作数的类型。 如果右操作数为负数,或者大于或等于提升左操作数的位数长度,则行为未定义。
在这种情况下,你不应该期待任何好事。
答案 2 :(得分:2)
<<
的两个操作数均为int
s,因此结果为int
。如果int
最大为32位宽,则在两种情况下都会发生有符号整数溢出;有符号整数溢出始终在C和C ++中都有未定义的行为。
然而,许多人错误地认为未定义的行为意味着结果是某些未指定的int
&#34;或者在他们的平台上,结果是1 << 32 (mod 2³²)
;但事实是,在64位平台上,编译器倾向于使用64位寄存器进行32位计算,因为知道计算永远不会在符合程序中溢出,因此在未定义行为的情况下,实际结果也可以是值它甚至不适合32位变量!