gpt4 book ai didi

C++编译错误?

转载 作者:IT老高 更新时间:2023-10-28 12:06:34 25 4
gpt4 key购买 nike

我有以下代码:

#include <iostream>
#include <complex>
using namespace std;

int main() {
complex<int> delta;
complex<int> mc[4] = {0};

for(int di = 0; di < 4; di++, delta = mc[di]) {
cout << di << endl;
}

return 0;
}

我希望它输出“0, 1, 2, 3”并停止,但它输出了无穷无尽的“0, 1, 2, 3, 4, 5, .....”系列

看起来像比较 di<4效果不好,总是返回true。

如果我只是注释掉 ,delta=mc[di] ,我正常得到“0、1、2、3”。无辜的分配有什么问题?

我正在使用 Ideone.com带有 -O2 选项的 g++ C++14。

最佳答案

这是由于未定义的行为,您正在访问数组 mc循环的最后一次迭代超出范围。一些编译器可能会围绕没有未定义行为的假设执行积极的循环优化。逻辑类似于以下内容:

  • 访问 mc越界是未定义的行为
  • 假设没有未定义的行为
  • 因此di < 4总是如此,否则mc[di]会调用未定义的行为

开启优化并使用 -fno-aggressive-loop-optimizations 的 gcc flag 导致无限循环行为消失 ( see it live )。而一个 live example with optimization but without -fno-aggressive-loop-optimizations展示您观察到的无限循环行为。

一个 godbolt live example of the code显示 di < 4 check 被移除并替换为 and unconditional jmp:

jmp .L6

这与 GCC pre-4.8 Breaks Broken SPEC 2006 Benchmarks 中概述的情况几乎相同。 .这篇文章的评论非常好,值得一读。它指出,clang 在文章中使用 -fsanitize=undefined 捕获了这个案例。对于这种情况,我无法重现,但 gcc 使用 -fsanitize=undefined确实( see it live )。围绕未定义行为进行推断的优化器最臭名昭著的错误可能是 Linux kernel null pointer check removal .

虽然这是一种激进的优化,但重要的是要注意,正如 C++ 标准所说的未定义行为是:

behavior for which this International Standard imposes no requirements

这本质上意味着一切皆有可能,它指出(强调我的):

[...]Permissible undefined behavior ranges from ignoring the situation completely with unpredictable results, to behaving during translation or program execution in a documented manner characteristic of the environment (with or without the issuance of a diagnostic message), to terminating a translation or execution (with the issuance of a diagnostic message).[...]

为了从 gcc 获得警告,我们需要移动 cout在循环之外,然后我们会看到以下警告 ( see it live ):

warning: iteration 3u invokes undefined behavior [-Waggressive-loop-optimizations]
for(di=0; di<4;di++,delta=mc[di]){ }
^

这可能足以为 OP 提供足够的信息来弄清楚发生了什么。像这样的不一致是我们可以看到的未定义行为的典型行为类型。为了更好地理解为什么这种警告在面对未定义的行为时会不一致 Why can't you warn when optimizing based on undefined behavior?很好读。

注意,-fno-aggressive-loop-optimizations记录在 gcc 4.8 release notes .

关于C++编译错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32506643/

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