为什么 gcc 不对内部代码中的未定义行为发出警告?

发布于 2024-12-18 06:39:28 字数 485 浏览 2 评论 0原文

我刚刚阅读了这个有关未定义行为和序列点的 SO C++ 常见问题解答,并进行了一些实验。在下面的代码中,gcc-4.5.2仅在代码注释中提到的行中给了我一个警告,尽管前面的一行也显示了未定义的行为,不是吗?您无法说出首先执行加法的哪个操作数(因为 + 不是序列点)。为什么 gcc 也不在这一行给我警告?

int i=0;
int j=0;

int foo(void) {
    i=1;
    return i;
}

int main(void) {
    i = i + foo(); 
    j = j + (j=1); //Here is a rightly warning
    return 0;
}

谢谢你的帮助。

I just read this SO C++ FAQ about undefined behavior and sequence points and experimented a bit. In the following code gcc-4.5.2 gives me a warning only in the line mentioned in the code comment, although the one line before shows undefined behaviour too, doesn't it? You can't say which operand of addition is executed first (as + is no sequence point). Why does gcc not give me a warning in this line too?

int i=0;
int j=0;

int foo(void) {
    i=1;
    return i;
}

int main(void) {
    i = i + foo(); 
    j = j + (j=1); //Here is a rightly warning
    return 0;
}

Thank you for helping.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

诗酒趁年少 2024-12-25 06:39:28

i = i + foo(); 的行为未指定但并非未定义。未定义意味着允许任何可能的行为,甚至中止程序。未指定意味着首先评估 i 或 foo()。是的, foo 写入同一个 i,但由于它发生在单独的语句中,因此该存储之前和之后都有一个序列点。

The behaviour of i = i + foo(); is unspecified but not undefined. Undefined means any possible behaviour is permitted, even aborting the program. Unspecified means either i is evaluated first, or foo(). Yes, foo writes to that same i, but since it happens in a separate statement, there is a sequence point before and after that store.

情深缘浅 2024-12-25 06:39:28

程序中的行 i = i + foo(); 未指定,但并非未定义。

编译器尝试发出没有误报的警告(每次编译器警告时,都存在程序员应该修复的缺陷),或者至少误报率非常低。这意味着,作为交换,他们有相当多的漏报。为了与同样的理念保持一致,编译器通常不会对未指定的行为发出警告。

要获得有关程序的警告,您应该研究静态分析器,它们对警告更积极,但误报率略高。静态分析器很可能决定对未指定的行为发出警告。其中一些甚至警告已定义的行为,尽管已定义,但表明程序员可能感到困惑。

The line i = i + foo(); in your program is unspecified but not undefined.

Compilers try to emit warnings without false positives (every time the compiler warn, there is a defect that the programmer should fix), or at least with very low rates of false positives. This means that in exchange, they have quite a few false negatives. In keeping with the same philosophy, compilers usually do not warn for unspecified behaviors.

To get a warning about your program, you should look into static analyzers, which are more aggressive about warnings, at the cost of slightly more false positives. Static analyzers can very well decide to warn about unspecified behaviors. Some of them even warn about defined behaviors that, although being defined, indicate that the programmer was probably confused.

隔岸观火 2024-12-25 06:39:28

对于人类来说,调用 foo() 会改变 i 是可见的,但对于计算机程序来说,这是很难看到的。它只是不是为了看到这一点而设计的。

It is visible to humans that calling foo() would alter i, but for a computer programme it is hard to see. It's just not designed to see this.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文