未初始化的警告需求-O2

时间:2019-05-09 10:32:38

标签: c++ gcc warnings

当我编译下面的C ++程序时,我需要添加-O2标志以获取有关未初始化变量的警告。为什么会这样?

unsigned long fac(unsigned long n)
{
  unsigned long product;

  while (n > 1)
  {
    product = product * n;
    n = n - 1;
  }

  return product;
}

➜  a g++ --version
g++ (GCC) 8.3.1 20190223 (Red Hat 8.3.1-2)

编辑:为澄清这个问题,我当然启用了警告。

3 个答案:

答案 0 :(得分:4)

警告在-O2(或任何其他优化)模式下显示,并且选项-Wmaybe-uninitialized处于打开状态。 -Wmaybe-uninitialized-Wall以及启用的任何优化模式都将打开。

根据GCC documentation这样做的原因是:

  

-Wmaybe-uninitialized

     

对于自动(即本地)变量,如果存在该函数的路径   使用已初始化的变量的条目,但是还存在其他一些变量   变量未初始化的路径,编译器将在以下情况下发出警告   它不能证明未初始化的路径在运行时未执行。   这些警告仅在优化编译中可用,因为否则   GCC不会跟踪变量的状态。这些警告是可选的,因为GCC可能无法确定   即使出现错误,代码仍然正确。

然后以一个示例说明上述情况如何发生。

答案 1 :(得分:1)

要更深入地回答为什么问题,这样做主要是为了减少误报率和编译时间。产生这些警告(-Wmaybe-uninitialized风格)的过程在编译管道中运行得很晚(请参阅gcc/passes.def;相应的pass_late_warn_uninitialized过程在第338行左右)。 GCC尽力为该警告生成尽可能少的误报。为此,它需要有关程序的更精确的信息。为了获得此信息,它需要事先进行一些分析/转换(例如,jump threading特别有益)。而且其中有些过于昂贵,无法在-O0上启用。

GCC开发是公开进行的。通常在邮件列表和bugzilla中讨论所有主要决策。例如,请参见this comment


答案 2 :(得分:-1)

未初始化的变量不是技术错误; x86 / x64程序集中的内存可以未初始化。从未初始化的内存中读取(受保护/长模式限制可以读取)是有效的。您将获得未定义的值,但在技术上有效。

显示给您的内容取决于编译器(因此,它是可用的选项)。较高级别的选项可能会将其视为错误并停止;但是从技术上讲,这是可能的。