该标准建议(通过省略)建议,即使移位的数字为负,左移位操作数的值也无关紧要,即使移位为零似乎应该定义清楚。为什么将其视为未定义行为(UB)?
int a( -1 ); //ok
int b( -1 << 0); //UB
答案 0 :(得分:0)
通常,您首先应该问一个问题:UB到底是什么,为什么?
它听起来并不简单。
例如。令x
为min 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 = 2147483647
(max integer
)将打印
x is bigger than x+1 2147483647 -2147483648
如果未应用优化(调试模式),但启用了-O2(发布模式),则很可能会打印
x is smaller than x+1 2147483647 -2147483648