将负整数左移零为未定义行为有意义吗?

时间:2019-05-25 05:12:11

标签: c++

该标准建议(通过省略)建议,即使移位的数字为负,左移位操作数的值也无关紧要,即使移位为零似乎应该定义清楚。为什么将其视为未定义行为(UB)?

    int a( -1     ); //ok
    int b( -1 << 0); //UB

1 个答案:

答案 0 :(得分:0)

通常,您首先应该问一个问题:UB到底是什么,为什么?

它听起来并不简单。

例如。令xmin integer。然后,即使我们知道答案是什么,也将其进一步降低视为UB。例如,将其减少1会将其更改为max integer

但是为什么呢?因为编译器/优化器假设减少整数会使其更小,并且它可以基于此假设来优化代码。如果将int降低到min integer以下,可能会导致代码中出现各种奇怪的错误。

那么,为什么左移负整数是UB?即使左移为0?

假设您有一个代码y = x << c,其中c是未签名的。编译器在这里可以假设x不是负数,否则它将是UB。因此,如果存在基于x为非负数且您将x与负数c = 0传递为负值的假设而优化的复杂逻辑依赖关系,则会导致代码随机发生意外行为尽管计算y = x << c十分合理,并且可以正确计算,但仍然可以放置。

(免责声明,我没有为<<运算符签出任何有关UB的特定内容,只是给出了有关C ++中UB的一般答案)

您可以在Internet上查看有关UB的更多信息。 YouTube上的CppCon中有几个视频。

编辑:关于由于UB而造成的异常行为。正在关注程序

if(x > x + 1)
{
    std::cout << " x is bigger than x+1 " << x << " " << x+1;
}
else
{
    std::cout << " x is smaller than x+1 " << x << " " << x+1;
}

使用x = 2147483647max integer)将打印

x is bigger than x+1 2147483647 -2147483648

如果未应用优化(调试模式),但启用了-O2(发布模式),则很可能会打印

x is smaller than x+1 2147483647 -2147483648