什么是gcc的Wmaybe-unitialized警告

时间:2015-11-29 11:19:05

标签: c++ gcc gcc-warning

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

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

现在我可以使用-Wno-maybe -ininitialized禁用警告或在代码中修复。

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

我正在使用GCC 4.8 Fedora 21 x86_64

如果有人能够证明这个警告是如何触发的,我也很感激。

2 个答案:

答案 0 :(得分:3)

在提出这些问题之前,你应该仔细查看GCC手册。

  

对于自动变量,如果存在来自该函数的路径   进入使用初始化的变量,但存在   该变量未初始化的其他一些路径,   如果编译器无法证明未初始化的路径,则会发出警告   不会在运行时执行。这些警告是可选的,因为   GCC不够聪明,无法查看代码可能出现的所有原因   尽管看起来有错误但也是正确的。

当GCC不确定变量是否已初始化时,不会生成此警告。在变量未始终初始化时发出。

以下是手册中略有修改的示例:

void foo(int y)
{
    int x;
    switch (y)
    {
        case 1: x = 1;
        break;
        case 2: x = 4;
        break;
        case 3: x = 5;
    }
    bar(x);
}

答案 1 :(得分:2)

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

void func1(int x);  

void func()
{
    int x;
    func1(x);   // x is definitely not initialized when calling func1;
}

但在某些情况下,变量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);
}

现在,如果您和我确定y 总是 onw或2,那么上面的代码没有问题。但是,如果我们将y称为三,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);
}

现在,编译器将知道assert的结果不允许y为1或2以外的任何值,因此涵盖了所有有效值。 <{1}}无法返回无效值。

[当然,标准并未声明assert具有此效果。这是呼叫流分析结合数据流分析和理解assert的作用 - 我知道gcc和clang都理解这种结构,并且很乐意在没有警告的情况下保留上述代码]