布尔值的左移和右移

Left shifts and right shifts on boolean

我正在尝试了解整数提升如何与算术移位运算符一起工作。特别是,我想知道 a, b, c, d, e, f, g, h 的哪些值是根据 C++14 标准准确定义的,哪些可以依赖于 platform/hardware/compiler(假设 sizeof(int) == 4)。

int a = true << 3;
int b = true >> 3;

int c = true << 3U;
int d = true >> 3U;

int e = true << 31;
int f = true >> 31;

int g = true << 31U;
int h = true >> 31U;

来自[expr.shift]:

The type of the result is that of the promoted left operand. The behavior is undefined if the right operand is negative, or greater than or equal to the length in bits of the promoted left operand.

移位 bool 的结果类型总是 int,不管右边是什么。我们永远不会移动至少 32 或负数,所以我们在所有方面都没有问题。

对于左移 (E1 << E2):

Otherwise, if E1 has a signed type and non-negative value, and E1×2E2 is representable in the corresponding unsigned type of the result type, then that value, converted to the result type, is the resulting value; otherwise, the behavior is undefined.

1×231unsigned int 表示,这是我们正在做的最大的左移,所以我们在所有帐户上都可以.

对于右移 (E1 >> E2):

If E1 has a signed type and a negative value, the resulting value is implementation-defined.

E1 永远不会是负数,所以我们也可以!任何地方都没有未定义或实现定义的行为。

以下主要是对Barry的回答的补充,清楚地解释了左右移位的规则。

至少对于 C++11,bool 的整数提升为 false 给出 0,为 true 给出 1:4.5 积分提升 [conv.prom] § 6

A prvalue of type bool can be converted to a prvalue of type int, with false becoming zero and true becoming one.

所以在原来的例子中,bdfh都会得到一个0值,ac 都得到一个 8 值:直到这里只有完美定义的行为。

但是 eg 将接收无符号值 0x80000000,所以如果你将它影响到一个无符号的 int 变量会很好,但是你使用的是有符号的 32 位整数。所以你得到一个积分转换:4.7积分转换[conv.integral]§3

If the destination type is signed, the value is unchanged if it can be represented in the destination type; otherwise, the value is implementation-defined.

并且无符号 0x80000000 不能用有符号的 64 位整数表示,因此结果是 实现定义 eg