布尔值左移和右移

时间:2015-10-13 18:51:10

标签: c++ standards c++14 bit-shift integer-promotion

我试图理解exaclty积分推广如何与算术移位运算符一起工作。特别是,我想知道,a, b, c, d, e, f, g, h的哪些值是根据C ++ 14标准准确定义的,哪些值可以依赖于平台/硬件/编译器(假设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;

2 个答案:

答案 0 :(得分:2)

来自[expr.shift]:

  

结果的类型是提升的左操作数的类型。如果右操作数,则行为未定义   是负的,或大于或等于提升的左操作数的位数。

bool的结果类型始终为int,无论右侧是什么。我们永远不会偏移至少32或负数,所以我们在所有帐户上都可以。

对于左移(E1 <&lt;&lt; E2):

  

否则,如果E1具有带符号类型且非负值,则E1×2 E2 可表示   在结果类型的相应无符号类型中,那么转换为结果类型的值是   结果价值;否则,行为未定义。

1×2 31 可由unsigned int表示,这是我们正在进行的最大左移,所以我们在所有帐户上也都可以。

对于右移(E1>&gt; E2):

  

如果E1具有有符号类型和负值,则结果值是实现定义的。

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

答案 1 :(得分:0)

以下主要是对巴里答案的补充,这清楚地解释了左右移动的规则。

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

  

bool类型的prvalue可以转换为int类型的prvalue,false变为零,true变为1。

因此,在原始示例中,bdfh都将获得0值,ac获得8值:直到此处才有完美定义的行为。

eg将收到无符号值0x80000000,因此如果您将其影响到unsigned int变量,但使用带符号的32位整数,则可以。所以你得到积分转换:4.7积分转换[conv.integral]§3

  

如果目标类型已签名,则该值如果可以在目标类型中表示,则不会更改;否则,该值是实现定义的。

无符号0x80000000在带符号的64位整数中无法表示,因此eg的结果为实现已定义