为什么相同的位运算会得到不同的结果?

Why the same bitwise operations give different results?

正在尝试关闭 MSB,同时打开所有其他位。

unsigned char a = ~0 << 1 >> 1;
printf("a: %d\n", a);

unsigned char b = ~0;
b <<= 1;
b >>= 1;
printf("b: %d\n", b);

打印输出给出:

a: 255
b: 127

适用整数提升规则。

The integer promotions are performed on each of the operands. The type of the result is that of the promoted left operand.

初始化的RHS:

unsigned char a = ~0 << 1 >> 1;

0转换为int,然后按位左右移位,最后赋值将结果转换为unsigned char。这意味着结果将为 255(假设 CHAR_BIT == 8)。从技术上讲,您有 未定义的行为:

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.

如果您使用:

,您将避免未定义的行为
unsigned char a = ~0U << 1 >> 1;

'multiple assignments' 版本(避免未定义的行为)等同于:

unsigned char a = (unsigned char)(~0U << 1) >> 1;

它会在重新提升右移类型之前截断左移的结果,并将产生 127 作为结果(仍然假设 CHAR_BIT == 8)。