左移是负数吗int
C++11 中未定义的行为?
这里的相关标准段落来自 5.8:
2/E1
让我困惑的部分是:
否则,如果 E1 具有有符号类型和非负值,且 E1×2E2
可以用结果类型表示,那么这就是结果值;
否则,行为是未定义的。
这是否应该被解释为左移any负数是UB?或者这仅仅意味着if你 LS 为负数,结果不符合结果类型,then是UB吗?
此外,前款还说:
1/移位运算符 > 从左到右分组。
移位表达式:
加法表达
移位表达式 > 加法表达式
操作数应为整数或无范围枚举类型,并且
进行积分促销。
结果的类型是提升后的左操作数的类型。这
如果右操作数为负或更大,则行为未定义
大于或等于提升的左操作数的位长度。
这明确表明使用负数one操作数中的 UB 为 UB。如果 UB 对另一个操作数使用负数,我希望这里也能清楚地说明这一点。
所以,底线是:
-1 << 1
未定义的行为?
@Angew provided https://stackoverflow.com/a/19594249/241536标准语言的伪代码解释,简洁地表达了一种可能(可能)有效的解释。其他人质疑这个问题是否真的是关于“行为未定义”语言的适用性与我们(StackOverflow)使用的短语“未定义行为”的适用性。此编辑是为了对我想问的问题提供更多澄清。
@Angew 对标准语的解释是:
if (typeof(E1) == unsigned integral)
value = E1 * 2^E2 % blah blah;
else if (typeof(E1) == signed integral && E1 >= 0 && representable(E1 * 2^E2))
value = E1 * 2^E2;
else
value = undefined;
这个问题真正归结为——实际上正确的解释是:
value = E1 left-shift-by (E2)
switch (typeof(E1))
{
case unsigned integral :
value = E1 * 2^E2 % blah blah;
break;
case signed integral :
if (E1 >= 0)
{
if (representable(E1 * 2^E2))
{
value = E1 * 2^E2;
}
else
{
value = undefined;
}
}
break;
}
?
旁注,从伪代码的角度来看,我很清楚@Agnew 的解释是正确的。
是的,我会说它是未定义的。如果我们将标准语言翻译成伪代码:
if (typeof(E1) == unsigned integral)
value = E1 * 2^E2 % blah blah;
else if (typeof(E1) == signed integral && E1 >= 0 && representable(E1 * 2^E2))
value = E1 * 2^E2;
else
value = undefined;
我想说的是,它们明确说明右侧操作数而不是左侧操作数的原因是您引用的段落(右侧操作数大小写的段落)适用于左移和右移。
对于左侧操作数,裁决有所不同。负数左移是未定义的,右移是实现定义的。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)