【问题标题】:GCC uninitialized variable check not working with `while`? [duplicate]GCC未初始化的变量检查不适用于`while`? [复制]
【发布时间】:2015-10-10 00:05:00
【问题描述】:

我最近在 C 上 answered a question,其中我建议打开所有编译器警告。

我想我会复制粘贴我确信 gcc 在编译 OP 代码时会给出的实际警告。

除了它不起作用。我把它归结为这个测试用例它也不起作用

int main() {
        int a; /* not initialised */

        while (a) { /* warn me! */
            a++;
        }

        return 0;
}

我会把我的最后一分钱赌在gcc 上:

test.c: In function ‘main’:
test.c:4:6: warning: ‘a’ is used uninitialized in this function   [-Wuninitialized]

 while (a) {
        ^

...我会输的。我没有收到任何警告!然而,如果我使用if 而不是while,为什么是的,那么我得到的正是那个警告。但是while?一点耳语都没有。

我查看了一些似乎密切相关的 reports 并得出结论,虽然它们不适用,但 gcc 可能做了一些事情,这使得警告在这种情况下是多余的.我想知道是什么。

是不是因为a被初始化为0?不,因为

int main() {
    int a;

    if (a == 0) { printf("a is zero\n"); }

    while (a == 0) { a = printf("a is zero\n"); }

    return 0;
}

在 if() 上给出错误,但如果我将 if() 注释掉,则不再给出错误。如果 gcc 知道 a 将是 0,那么第一个 if 也应该不会引发错误。

那么这里发生了什么?

【问题讨论】:

  • 嘿,如果没有你的副本,我不会阅读任何的!很有教育意义。

标签: c gcc undefined-behavior gcc-warning


【解决方案1】:

这不是错误。这是一个实施质量问题。如果我们查看manual,它指出:

请注意,可能没有关于仅使用的变量的警告 计算一个本身从未使用过的值,因为这样 计算可能会在警告前被数据流分析删除 被打印出来。

确实如下:

int b = a++;

确实会引发警告。

main.cpp:6:16: warning: variable 'a' is uninitialized when used here [-Wuninitialized]
        while (a) { /* warn me! */
               ^

main.cpp:4:14: note: initialize the variable 'a' to silence this warning
        int a; /* not initialised */
             ^
              = 0

原来的例子有printf,但这让人困惑,因为它暗示了与“as-if”规则的关系。

真的,你能做的最好的事情是:

  • 接受对每一种可能的情况发出警告就等同于解决停机问题

  • 报告给开发者,希望他们做点什么

  • 使用替代方案。 Clang 确实提供警告

  • 查看来自 GCC wiki 的 "Better Uninitialized Warnings"。支持该项目。请记住,硬币有两个方面。 GCC is notorious for bogus warnings 也是。

【讨论】:

  • 确认一下,您是说a 的整个生命周期都没有影响,可以完全优化掉。很高兴听到这会如何影响警告诊断!
  • @underscore_d 不一定,优化与否与没有警告无关。
  • 是的,我的措辞并不理想。我的意思是没有副作用,而且我没有意识到一些警告会受到影响。
  • fwiw 一个骗子建议,如果它的输出是用于流分析的输入,则确实可能涉及优化stackoverflow.com/questions/29313855/…
  • 其实,这一个错误(gcc.gnu.org/bugzilla/show_bug.cgi?id=18501)。为了反驳您的示例,我添加了int a, b;,然后将a 分配给b,并将b 打印到标准输出,gcc -W -Wall 甚至没有抽搐。可能在 C++ 模式下,行为是不同的。然而,重复的答案建议为这些检查安装 clang
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-26
相关资源
最近更新 更多