为什么此代码会为f1
和f2
打印两个不同的数字?:
int main() {
int a = 32;
int f1 = (0xffffffff << a);
int f2 = (0xffffffff << 32);
std::cout << f1 << std::endl; // print -1
std::cout << f2 << std::endl; // print 0
}
对于f2,我收到此警告但f1:
没有警告:左移计数&gt; =类型宽度
我正在使用g ++ 4.4.7
答案 0 :(得分:2)
简短的回答是invoking undefined behavior when shifting by width of type or greater。
更长的答案是,对于第二种情况,gcc可以不断折叠表达式,只是移动到零( see it live on godbolt ):
movl $0, -28(%rbp) #, f2
虽然在第一种情况下它实际上执行了转变:
movl -20(%rbp), %eax # a, tmp63
movl $-1, %edx #, tmp64
movl %edx, %ebx # tmp64,
movl %eax, %ecx #,
sall %cl, %ebx #,
movl %ebx, %eax #, D.21248
movl %eax, -24(%rbp) # D.21248, f1
由于我们正在调用未定义的行为,因此我们对结果没有任何期望。看似应该提供相同答案的不一致的答案是完全可以接受的未定义行为。
答案 1 :(得分:1)
的结果
0xffffffff << 32
是
18446744069414584320
远远大于std::numeric_limits<int>::max()
如果您的系统将int
表示为4个字节,则上述值为
2147483647
Signed overflow is undefined behavior所以两者都表现出未定义的行为。