未初始化警告需要-O2
Uninitialized warning needs -O2
当我编译以下 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)
编辑:为了澄清问题,我当然启用了警告。
未初始化的变量不是技术错误; x86/x64 程序集中的内存可以未初始化。从未初始化的内存(可通过 protected/long 模式限制读取)读取是有效的。您将得到未定义的值,但在技术上有效。
它向您显示的内容取决于编译器(因此,它是可用选项)。更高级别的选项可能会将此视为错误并停止;但从技术上讲这是可能的。
警告出现在 -O2(或任何其他优化)模式下,同时选项 -Wmaybe-uninitialized
已打开。 -Wmaybe-uninitialized
选项也随着 -Wall
和启用的任何优化模式而打开。
根据 GCC documentation 的原因是:
-Wmaybe-uninitialized
For an automatic (i.e. local) variable, if there exists a path from the function
entry to a use of the variable that is initialized, but there exist some other
paths for which the variable is not initialized, the compiler emits a warning if
it cannot prove the uninitialized paths are not executed at run time.
These warnings are only possible in optimizing compilation, because otherwise
GCC does not keep track of the state of variables. These warnings are made optional because GCC may not be able to determine
when the code is correct in spite of appearing to have an error.
然后举例说明上述情况是如何发生的。
为了更深入地回答 why 问题,这样做主要是为了减少误报率和编译时间。产生这些警告的通道(-Wmaybe-uninitialized
风格)在编译管道中 运行 非常晚(参见 gcc/passes.def
;相应的 pass_late_warn_uninitialized
通道在第 338 行左右). GCC 努力尽可能减少此警告的误报。为此,它需要有关该程序的更准确信息。要获得此信息,它需要预先执行一些 analyses/transformations(例如,jump threading 特别有用)。其中一些太贵了,无法在 -O0
.
启用
GCC 开发是公开进行的。所有主要决定通常都在邮件列表和 bugzilla 中讨论。参见,例如,this comment.
当我编译以下 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)
编辑:为了澄清问题,我当然启用了警告。
未初始化的变量不是技术错误; x86/x64 程序集中的内存可以未初始化。从未初始化的内存(可通过 protected/long 模式限制读取)读取是有效的。您将得到未定义的值,但在技术上有效。
它向您显示的内容取决于编译器(因此,它是可用选项)。更高级别的选项可能会将此视为错误并停止;但从技术上讲这是可能的。
警告出现在 -O2(或任何其他优化)模式下,同时选项 -Wmaybe-uninitialized
已打开。 -Wmaybe-uninitialized
选项也随着 -Wall
和启用的任何优化模式而打开。
根据 GCC documentation 的原因是:
-Wmaybe-uninitialized
For an automatic (i.e. local) variable, if there exists a path from the function entry to a use of the variable that is initialized, but there exist some other paths for which the variable is not initialized, the compiler emits a warning if it cannot prove the uninitialized paths are not executed at run time. These warnings are only possible in optimizing compilation, because otherwise GCC does not keep track of the state of variables. These warnings are made optional because GCC may not be able to determine when the code is correct in spite of appearing to have an error.
然后举例说明上述情况是如何发生的。
为了更深入地回答 why 问题,这样做主要是为了减少误报率和编译时间。产生这些警告的通道(-Wmaybe-uninitialized
风格)在编译管道中 运行 非常晚(参见 gcc/passes.def
;相应的 pass_late_warn_uninitialized
通道在第 338 行左右). GCC 努力尽可能减少此警告的误报。为此,它需要有关该程序的更准确信息。要获得此信息,它需要预先执行一些 analyses/transformations(例如,jump threading 特别有用)。其中一些太贵了,无法在 -O0
.
GCC 开发是公开进行的。所有主要决定通常都在邮件列表和 bugzilla 中讨论。参见,例如,this comment.