是否将8*sizeof(int)或更多未定义的签名int右移?

FSM*_*axB 4 c bit-shift undefined-behavior

我知道这是未定义的:

uint32_t u = 1;
u << 32;
Run Code Online (Sandbox Code Playgroud)

但我对哪种类型的转变未定义感到有些困惑.

是否未定义将有符号整数按其大小(以位为单位)或更多向右移位?

更新:正如答案中所指出的,这是以位为单位的大小,而不是以字节为单位.

Kei*_*son 6

sizeof (int)是以int 字节为单位的大小,因此它不相关.相关的不是大小,而是宽度,即表示中的值位数(加上有符号类型的符号位).

如果<<>>运算符的右操作数大于或等于提升的左操作数的宽度,则行为未定义.(例如,如果左操作数是类型short,则int在应用操作之前将其提升为).

对于<<左移运算符,仅当左操作数为非负且结果可表示时才定义行为.

对于>>右移运算符,如果左操作数为负,则结果为实现定义.

这一点在C标准的第6.5.7节中定义(链接到N1570,最新公开的C11草案).

以下是语义的完整描述:

对每个操作数执行整数提升.结果的类型是提升的左操作数的类型.如果右操作数的值为负或大于或等于提升的左操作数的宽度,则行为未定义.

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

结果E1 >> E2E1右移位E2位置.如果E1具有无符号类型或者E1具有有符号类型和非负值,则结果的值是E1/ 的商的整数部分.如果 具有有符号类型和负值,则结果值是实现定义的.2E2E1