简体   繁体   English

布尔值左移和右移

[英]Left shifts and right shifts on boolean

I am trying to understand exaclty how integral promotion works with arithmetic shifts operators. 我试图理解exaclty积分推广如何与算术移位运算符一起工作。 Particularly, I would like to know, which values of a, b, c, d, e, f, g, h are exactly defined according to the C++14 standard, and which ones can depend on the platform/hardware/compiler (assuming that sizeof(int) == 4 ). 特别是,我想知道, 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;

From [expr.shift]: 来自[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. 如果右操作数为负数,或者大于或等于提升左操作数的位长度,则行为未定义。

The result type of shifting a bool is always int , regardless of what's on the right hand side. 无论右侧是什么,移动bool的结果类型总是int We're never shifting by at least 32 or by a negative number, so we're ok there on all accounts. 我们永远不会偏移至少32或负数,所以我们在所有帐户上都可以。

For the left-shifts (E1 << E2): 对于左移(E1 << E2):

Otherwise, if E1 has a signed type and non-negative value, and E1×2 E2 is representable in the corresponding unsigned type of the result type, then that value, converted to the result type, is the resulting value; 否则,如果E1具有有符号类型和非负值,并且E1×2 E2在结果类型的相应无符号类型中可表示,则转换为结果类型的该值是结果值; otherwise, the behavior is undefined. 否则,行为未定义。

1×2 31 is representable by unsigned int , and that's the largest left-shift we're doing, so we're ok there on all accounts too. 1×2 31可以用unsigned int表示,这是我们正在做的最大的左移,所以我们在所有帐户上都可以。

For the right-shifts (E1 >> E2): 对于右移(E1 >> E2):

If E1 has a signed type and a negative value, the resulting value is implementation-defined. 如果E1具有带符号类型和负值,则结果值是实现定义的。

E1 is never negative, so we're ok there too! E1永远不会消极,所以我们也可以! No undefined or implementation-defined behavior anywhere. 任何地方都没有未定义或实现定义的行为。

Following is mainly a complement to Barry's answer, that clearly explains the rules for left and right shifting. 以下主要是对巴里答案的补充,这清楚地解释了左右移位的规则。

At least fo C++11, the integral promotion of a bool gives 0 for false and 1 for true : 4.5 Integral promotions [conv.prom] § 6 至少对于C ++ 11,bool的整体提升为0表示false ,1表示true :4.5 Integral promotion [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. bool类型的prvalue可以转换为int类型的prvalue,false变为零,true变为1。

So in original examples, b , d , f and h will all get a 0 value, a and c both get a 8 value: only perfectly defined behaviour until here. 因此在原始示例中, bdfh都将获得0值, ac都获得8值:直到此处才有完美定义的行为。

But e and g will receive the unsigned value 0x80000000 , so it would be fine if you affected it to an unsigned int variable, but you are using signed 32 bits integers. 但是eg将接收无符号值0x80000000 ,所以如果你将它影响到unsigned int变量就可以了,但你使用的是带符号的32位整数。 So you get an integral conversion : 4.7 Integral conversions [conv.integral] §3 所以你得到一个积分转换 :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. 否则,该值是实现定义的。

And unsigned 0x80000000 is not representable in a signed 64 bits integer so the result is implementation defined for e and g . 无符号0x80000000在有符号的64位整数中无法表示,因此结果是为eg 定义实现

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM