什么是海湾合作委员会的Wmaybe单位化警告

what is gcc's Wmaybe-unitialized warning

本文关键字:Wmaybe 单位 警告 委员会 什么      更新时间:2023-10-16

我知道gcc中有一个未初始化的警告,它可以告诉您变量是否未初始化。这一点我很清楚。但我想知道什么是";也许已初始化";警告

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

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

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

我使用的是GCC 4.8 Fedora 21 x86_64。

此外,如果有人能展示这个警告是如何触发的,我将不胜感激。

在某些情况下,编译器可以清楚地检测到某些东西没有初始化:

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);
}

现在,如果您和我确信yALWAYSonw或两个,那么上面的代码就没有问题。然而,如果我们用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以外的任何值,因此所有有效值都被覆盖。无效值被不返回的assert捕获。

[当然,标准中并没有说明assert具有这种效果。这是调用流分析与数据流分析以及对assert功能的理解的一种效果——我知道gcc和clang都理解这种结构,并且会很乐意毫无征兆地接受上面的代码]

在提出此类问题之前,您应该仔细阅读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);
}