什么是 gcc 的 Wmaybe-unitialized 警告

rkm*_*rkm 1 c++ gcc gcc-warning

我知道 gcc 中有一个未初始化的警告,可以告诉您变量是否未初始化。这对我来说很清楚。但我想知道什么是“Maybe-Initialized”警告?

gcc 不确定这是否已初始化。或者考虑一下,代码正确初始化,gcc 认为“可能”它没有初始化。如果编译器不确定为什么我应该有这个警告?

现在我可以禁用警告-Wno-maybe-uninitialized或在代码中进行修复。

但我的问题是这意味着什么?为什么 gcc 认为它可能未初始化。gcc 确定变量已初始化,因为我没有得到-Wuninitialized.

我正在使用 GCC 4.8 Fedora 21 x86_64。

另外,如果有人可以展示如何触发此警告,我将不胜感激。

Mat*_*son 7

在某些情况下,编译器可以清楚地检测到某些内容未初始化:

void func1(int x);  

void func()
{
    int x;
    func1(x);   // x is definitely not initialized when calling func1;
}
Run Code Online (Sandbox Code Playgroud)

但在某些情况下,变量 CAN 已被初始化:

void func(int y)
{
   int x;
   if (y == 1)
       x = 7;
   else if (y == 2)
       x = 14;
   // If we get here, is x initialized or not?
   func1(x);
}
Run Code Online (Sandbox Code Playgroud)

现在,如果你和我知道肯定y始终ONW或两个,那么上面的代码没有问题。但是,如果我们用yas 3调用它,x则尚未初始化,并将func1对未指定的值进行操作。如果启用-Wmaybe-uninitialized,编译器会针对这种情况发出警告。

解决方法是告诉编译器不要期望任何其他值,例如使用assert

void func(int y)
{
   int x;
   assert( y == 1 || y == 2 && "Can't deal with y not in { 1, 2 } ");
   if (y == 1)
       x = 7;
   else if (y == 2)
       x = 14;
   // If we get here, is x initialized or not?
   func1(x);
}
Run Code Online (Sandbox Code Playgroud)

现在,编译器将知道 的结果assert不允许y是 1 或 2 以外的任何值,因此所有有效值都被覆盖。无效值被assert不返回的捕获。

[当然,标准并没有说明assert具有这种效果。这是调用流分析与数据流分析和对作用的理解相结合的结果assert- 我知道 gcc 和 clang 都理解这种结构,并且会很高兴地在没有警告的情况下接受上述代码]