gpt4 book ai didi

c++ - 左移 (<<) 是 C++11 中的负整数未定义行为吗?

转载 作者:IT老高 更新时间:2023-10-28 23:17:03 45 4
gpt4 key购买 nike

左移是否是负数int C++11 中的未定义行为?

这里的相关标准段落来自5.8:

2/The value of E1 << E2 is E1 left-shifted E2 bit positions; vacated bits are zero-filled. If E1 has an unsigned type, the value of the result is E1 × 2E2, reduced modulo one more than the maximum value representable in the result type. Otherwise, if E1 has a signed type and non-negative value, and E1×2E2 is representable in the result type, then that is the resulting value; otherwise, the behavior is undefined.

让我困惑的部分是:

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

这是否应该解释为左移任何负数是UB?或者它是否仅意味着如果你 LS 是否定的并且结果不适合结果类型,那么它是 UB?

而且,前面的子句说:

1/The shift operators << and >> group left-to-right. shift-expression: additive-expression shift-expression << additive-expression shift-expression >> additive-expression

The operands shall be of integral or unscoped enumeration type and integral promotions are performed.

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.

这清楚地表明,对 一个 操作数使用负数是 UB。如果是 UB 对另一个操作数使用负数,我希望在这里也能清楚地说明这一点。

所以,底线是:

-1 << 1

未定义的行为?


@Angew provided Standardese 的伪代码解释,简洁地表达了一种可能(可能)有效的解释。其他人质疑这个问题是否真的是关于“行为未定义”这一语言的适用性与我们(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;

我要说的是,他们明确指出右手操作数而不是左手操作数的原因是您引用的 paragrpah(具有右手操作数大小写的那个)适用于左手和右移。

对于左手操作数,规则不同。左移负数是未定义的,右移是实现定义的。

关于c++ - 左移 (<<) 是 C++11 中的负整数未定义行为吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19593938/

45 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com