1 << 31产生错误,"'''表达式的结果未定义"

Wil*_*ill 2 c c++

如果我在32位平台上声明了int类型的值并执行以下操作:

int32_t mask;
mask = 1 << 31: // produces 2147483648 (or 0x80000000)
Run Code Online (Sandbox Code Playgroud)

有人可以帮助我理解为什么上述行会产生警告:

The result of the '<<' expression is undefined
Run Code Online (Sandbox Code Playgroud)

T.C*_*.C. 10

2 31在a中不可表示,int32_t从-2 31变为(2 31 -1).这是C11和C++ 11中的未定义行为,以及C++ 14中定义的实现.

C11§6.5.7/ p4(引用N1570):

结果E1 << E2E1左移位E2位置; 腾出的位用零填充.[...]如果E1有一个带符号的类型和非负值,并且E1 × 2E2可以在结果类型中表示,那么这就是结果值; 否则,行为未定义.

N3337§5.8[expr.shift]/p2中的C++ 11规则几乎完全相同.由于2 31不可表示,因此行为未定义.

C++14§5.8[expr.shift]/p2(引用N3936;另见CWG第1457期):

E1 << E2E1左移位E2位置; 空位是零填充的.[...]否则,如果E1具有有符号类型和非负值,并且E1×2E2在结果类型的相应无符号类型中可表示,则转换为结果类型的该值是结果值; 否则,行为未定义.

由于2 31在无符号32位int中可表示,因此定义了行为并将结果转换为2 31int32_t ; 此转换是根据§4.7[conv.integral]/p3实现定义的.在使用二进制补码的典型系统中,你得到-2 31.