gpt4 book ai didi

c - "iteration ... invokes undefined behavior [-Waggressive-loop-optimizations]"警告的不明显原因

转载 作者:太空宇宙 更新时间:2023-11-04 08:06:03 26 4
gpt4 key购买 nike

在调查问题时,我偶然发现了代码,它归结为以下示例:

const unsigned long long int MAX=9223372036854775807ULL; //2^63-1
void double_it(double *d){
for(unsigned long long int i=0;i<MAX; i++){
d[i]=2*d[i];
}
}

由于一些错误,for 循环运行的距离远远超过内存,程序崩溃了。但这不是有趣的部分。

当使用 gcc (gcc -O2 -Wall -std=c99 -c) 编译时,此代码会导致以下警告:

warning: iteration 2305843009213693951ull invokes undefined behavior [-Waggressive-loop-optimizations]

这是我不明白的原因。

stackoverflow上有一些类似的问题,例如:

  1. g++ "warning: iteration ... invokes undefined behavior" for Seemingly Unrelated Variable
  2. Why does this loop produce "warning: iteration 3u invokes undefined behavior" and output more than 4 lines?

但那些问题是整数溢出,这里的计数器 i 似乎远未溢出。

在没有-O2的情况下编译相同的代码不会导致这样的警告,所以我猜-Waggressive-loop-optimizations是一个重要的部分。

其实我有两个问题:

  1. 这段代码(为 Linux x86-64 编译)有什么问题?
  2. 为什么没有 -O2 就没有警告?如果这段代码有问题,无论是否优化,我都认为它是有问题的。

g++ 的行为是相同的(在线查看 coliru)。

最佳答案

But those problems were integer overflows, here the counter i is seemingly nowhere near an overflow.

为什么会这样想?

d[i]*(d + i) 相同。 d + i 明显溢出,因为 double 的大小超过 2(不确定标准中是否有任何说明,但可以很安全地假设您的架构就是这样)。准确地说,sizeof 与此并不完全相关,但这是代码在编译器内部转换成的内容。

在 C11 §6.5.6 中我们可以读到:

If both the pointer operand and the result point to elements of the same array object, or one past the last element of the array object, the evaluation shall not produce an overflow; otherwise, the behavior is undefined

我们可以颠倒那句话的逻辑。如果加法明显溢出,那么一定是未定义的行为。

您没有收到警告的原因是编译器没有义务就所有未定义的行为向您发出警告。这是编译器的礼貌。通过优化,编译器会花更多时间推理代码的作用,因此它有机会发现更多不良行为。如果不进行优化,它不会浪费时间这样做。

关于c - "iteration ... invokes undefined behavior [-Waggressive-loop-optimizations]"警告的不明显原因,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42859795/

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