如果我在32位平台上声明了int类型的值并执行以下操作:
int32_t mask;
mask = 1 << 31: // produces 2147483648 (or 0x80000000)
有人可以帮助我理解上述行会产生警告的原因:
The result of the '<<' expression is undefined
答案 0 :(得分:10)
2 31 在int32_t
中无法表示,从-2 31 到(2 31 -1) )。这是C11和C ++ 11中的未定义行为,以及C ++ 14中定义的实现。
C11§6.5.7/ p4(引用N1570):
E1 << E2
的结果是E1
左移E2
位位置; 腾出的位用零填充。 [...]如果E1
有签名类型 和非负值,E1 × 2
E2
可表示 结果类型,那就是结果值;否则, 行为未定义。
N3337§5.8[expr.shift] / p2中的C ++ 11规则几乎完全相同。由于2 31 不可表示,因此行为未定义。
C ++14§5.8[expr.shift] / p2(引用N3936;另见CWG issue 1457):
E1 << E2
的值为E1
左移E2
位位置; 空位是零填充的。 [...]否则,如果E1
已签名 类型和非负值,E1×2
E2
是可表示的 在结果类型的相应无符号类型中,然后 转换为结果类型的值是结果值; 否则,行为未定义。
由于2 31 在无符号32位int中可表示,因此定义了行为,结果是2 31 转换为int32_t
;此转换是根据§4.7[conv.integral] / p3实现定义的。在使用二进制补码的典型系统中,你得到-2 31 。