按类型宽度移位不 return 零
Shift by type width does not return zero
对于简单的混淆分配,我需要移动一个 unsigned int
直到它变为零。
unsigned int a = 12;
a <<= sizeof(a) * 8;
printf("%u", a);
我使用 gcc test.c -o bin
编译它,GCC 警告:
warning: left shift count >= width of type [-Wshift-count-overflow]
当我执行它时,它returns 12
。但毫无疑问应该是0
。 GCC 是否忽略了编译那行代码?或者我遗漏了什么?
这是未定义的行为。
In any case, if the value of the right operand [of << or >>] is negative or is greater or equal to the number of bits in the promoted left operand, the behavior is undefined.
(引自 http://en.cppreference.com/w/cpp/language/operator_arithmetic)
另外,文章说:
- 无符号上溢和下溢定义明确,多余的位被截断。
<<
的有符号溢出未定义。 (自 C++14 起,如果结果值可以用左类型的无符号版本表示,则定义明确。然后将结果转换回有符号。)
>>
应用于带符号的底片是实现定义的。 (Cppreference 说在大多数架构上它复制最左边的位。)
<<
应用于带符号的底片未定义。
这些规则对于 C 和 C++ 是相同的。这是C11标准的相关部分:
6.5.7 移位运算符
- The integer promotions are performed on each of the operands. The type of the result is
that of the promoted left operand. If the value of the right operand is negative or is
- The result of E1 << E2 is E1 left-shifted E2 bit positions; vacated bits are filled with
zeros. If E1 has an unsigned type, the value of the result is E1 × 2E2, reduced modulo
one more than the maximum value representable in the result type. If E1 has a signed
type and nonnegative value, and E1 × 2E2 is representable in the result type, then that is
the resulting value; otherwise, the behavior is undefined.
- The result of E1 >> E2 is E1 right-shifted E2 bit positions. If E1 has an unsigned type
or if E1 has a signed type and a nonnegative value, the value of the result is the integral
part of the quotient of E1 / 2E2. If E1 has a signed type and a negative value, the
resulting value is implementation-defined.
对于简单的混淆分配,我需要移动一个 unsigned int
直到它变为零。
unsigned int a = 12;
a <<= sizeof(a) * 8;
printf("%u", a);
我使用 gcc test.c -o bin
编译它,GCC 警告:
warning: left shift count >= width of type [-Wshift-count-overflow]
当我执行它时,它returns 12
。但毫无疑问应该是0
。 GCC 是否忽略了编译那行代码?或者我遗漏了什么?
这是未定义的行为。
In any case, if the value of the right operand [of << or >>] is negative or is greater or equal to the number of bits in the promoted left operand, the behavior is undefined.
(引自 http://en.cppreference.com/w/cpp/language/operator_arithmetic)
另外,文章说:
- 无符号上溢和下溢定义明确,多余的位被截断。
<<
的有符号溢出未定义。 (自 C++14 起,如果结果值可以用左类型的无符号版本表示,则定义明确。然后将结果转换回有符号。)>>
应用于带符号的底片是实现定义的。 (Cppreference 说在大多数架构上它复制最左边的位。)<<
应用于带符号的底片未定义。
这些规则对于 C 和 C++ 是相同的。这是C11标准的相关部分:
6.5.7 移位运算符
- The integer promotions are performed on each of the operands. The type of the result is that of the promoted left operand. If the value of the right operand is negative or is
- The result of E1 << E2 is E1 left-shifted E2 bit positions; vacated bits are filled with zeros. If E1 has an unsigned type, the value of the result is E1 × 2E2, reduced modulo one more than the maximum value representable in the result type. If E1 has a signed type and nonnegative value, and E1 × 2E2 is representable in the result type, then that is the resulting value; otherwise, the behavior is undefined.
- The result of E1 >> E2 is E1 right-shifted E2 bit positions. If E1 has an unsigned type or if E1 has a signed type and a nonnegative value, the value of the result is the integral part of the quotient of E1 / 2E2. If E1 has a signed type and a negative value, the resulting value is implementation-defined.