gpt4 book ai didi

c++ - 执行时溢出/下溢是未定义的行为吗?

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:23:17 25 4
gpt4 key购买 nike

我正在阅读有关未定义行为的信息,我不确定它是否只是编译时的特性,或者它是否可以在执行时发生。

我很理解这个例子(这是从 Undefined Behavior page of Wikipedia 中提取的):

An example for the C language:

int foo(unsigned x)
{
int value = 5;
value += x;
if (value < 5)
bar();
return value;
}

The value of x cannot be negative and, given that signed integer overflow is undefined behavior in C, the compiler can assume that at the line of the if check value >= 5. Thus the if and the call to the function bar can be ignored by the compiler since the if has no side effects and its condition will never be satisfied. The code above is therefore semantically equivalent to:

int foo(unsigned x)
{
int value = 5;
value += x;
return value;
}

但这发生在编译时。

如果我写,例如:

void foo(int x) {
if (x + 150 < 5)
bar();
}

int main() {
int x;
std::cin >> x;
foo(x);
}

然后用户输入 MAX_INT - 100(“2147483547”,如果是 32 位整数)。

会出现整数溢出,但是据我所知,会产生溢出的是 CPU 的算术逻辑单元,所以这里不涉及编译器。

它仍然是未定义的行为吗?

如果是,编译器如何检测溢出?

我能想到的最好的是 CPU 的溢出标志。如果是这样,是否意味着只要在执行时随时设置 CPU 的溢出标志,编译器就可以为所欲为?

最佳答案

是的,但不一定是我认为你可能想要的方式,也就是说,如果在机器代码中有一个加法并且在运行时加法包装(或以其他方式溢出,但在大多数架构上它会包装)那本身不是 UB。 UB 仅属于 C(或 C++)领域。该添加可能一直在添加无符号整数或者是编译器可以进行的某种优化,因为它知道目标平台的语义并且可以安全地使用依赖于包装的优化(但是 不能,除非你使用无符号类型。

当然,这并不意味着使用“仅在运行时包装”的结构是安全的,因为这些代码路径在编译时也会被污染。例如在你的例子中,

extern void bar(void);

void foo(int x) {
if (x + 150 < 5)
bar();
}

由针对 x64 的 GCC 6.3 编译为

foo:
cmp edi, -145
jl .L4
ret
.L4:
jmp bar

相当于

void foo(int x) {
if (x < -145)
bar(); // with tail call optimization
}

.. 如果您假设有符号整数溢出是不可能的(从某种意义上说,它在输入上放置了一个隐式前提条件,以使溢出不会发生),这也是一样的。

关于c++ - 执行时溢出/下溢是未定义的行为吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41558924/

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