繁体   English   中英

布尔值左移和右移

[英]Left shifts and right shifts on boolean

我试图理解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;

来自[expr.shift]:

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

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

对于左移(E1 << E2):

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

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

对于右移(E1 >> E2):

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

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

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

至少对于C ++ 11,bool的整体提升为0表示false ,1表示true :4.5 Integral promotion [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 定义实现

暂无
暂无

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

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