gpt4 book ai didi

c++ - C++ 中的有符号溢出和未定义行为 (UB)

转载 作者:行者123 更新时间:2023-12-02 04:52:40 37 4
gpt4 key购买 nike

我想知道如何使用如下代码

int result = 0;
int factor = 1;
for (...) {
result = ...
factor *= 10;
}
return result;

如果循环迭代 n 次,则 factor 会乘以 10 恰好 n 次。但是,factor 仅在乘以 10 总共 n-1 次后才会使用。如果我们假设 factor 除了在循环的最后一次迭代之外永远不会溢出,但可能在循环的最后一次迭代时溢出,那么这样的代码是否可以接受?在这种情况下,发生溢出后,factor 的值将永远不会被使用。

我正在争论是否应该接受这样的代码。可以将乘法放在 if 语句中,并且在循环的最后一次迭代可能溢出时不进行乘法。缺点是它会使代码困惑并添加不必要的分支,需要检查所有先前的循环迭代。我还可以少迭代一次循环,并在循环后复制一次循环体,同样,这会使代码变得复杂。

有问题的实际代码用于紧密的内循环,该循环消耗了实时图形应用程序中总 CPU 时间的很大一部分。

最佳答案

编译器确实假设有效的 C++ 程序不包含 UB。例如考虑:

if (x == nullptr) {
*x = 3;
} else {
*x = 5;
}

如果x == nullptr则取消引用它并分配一个值是UB。因此,在有效程序中结束的唯一方法是当 x == nullptr 永远不会产生 true 并且编译器可以假设根据 as if 规则,上面相当于:

*x = 5;

现在在您的代码中

int result = 0;
int factor = 1;
for (...) { // Loop until factor overflows but not more
result = ...
factor *= 10;
}
return result;

factor 的最后一个乘法不能发生在有效的程序中(有符号溢出未定义)。因此,对 result 的赋值也不会发生。由于无法在最后一次迭代之前进行分支,因此前一次迭代也不会发生。最终,正确的代码部分(即,不会发生未定义的行为)是:

// nothing :(

关于c++ - C++ 中的有符号溢出和未定义行为 (UB),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59105498/

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