C 关于潜在未初始化变量的编译器警告

C 关于潜在未初始化变量的编译器警告,c,gcc,error-handling,gcc-warning,C,Gcc,Error Handling,Gcc Warning,考虑下面的伪代码,它使用典型的错误处理策略和错误代码变量: (Edit1:当出现uninit var警告时,我添加了另一个用例。不,虽然此伪代码是可编译的,但实际上不会触发GCC警告(v4.9.2)。但实际(更大)的代码在精神上与此伪代码相同。) GCC将发出警告,指出变量“a”可能未初始化 典型的解决方案是只添加(例如)a=0在函数的开头。但我在寻找更普通/优雅的东西。(编译器无法优化冗余初始化。并非每个变量都有合理的默认值。) 我的问题是:如果未设置err,是否有任何编译器功能可以告诉编译器

考虑下面的伪代码,它使用典型的错误处理策略和错误代码变量:

(Edit1:当出现uninit var警告时,我添加了另一个用例。不,虽然此伪代码是可编译的,但实际上不会触发GCC警告(v4.9.2)。但实际(更大)的代码在精神上与此伪代码相同。)

GCC将发出警告,指出变量“a”可能未初始化

典型的解决方案是只添加(例如)
a=0在函数的开头。但我在寻找更普通/优雅的东西。(编译器无法优化冗余初始化。并非每个变量都有合理的默认值。)

我的问题是:如果未设置
err
,是否有任何编译器功能可以告诉编译器
func1()
会初始化
a
?或者通过错误处理策略实现这一点的任何其他方法


另外,考虑到这种类型的错误处理非常普遍,我很困惑,我没有找到方法在没有不必要的赋值的情况下生成无警告代码。

所有非静态变量在定义之前都是未声明的,除非它们定义了默认构造函数。大多数基本类型被认为是基本类型,可以从C继承并遵循C的体系结构-在这种情况下,编译器将确定大小,并将在堆栈上分配此大小,不多也不少-底层内存是随机的,或者本质上是未定义的

如果是静态的,声明的变量如果未定义,则初始化为零 否则

所有非静态变量在声明之前都保留在内存段中的任何位置-这可能会导致未定义的行为,在极端情况下,还会导致信息泄漏。此外,如果使用堆内存,最好在C中调用calloc而不是malloc,在C++中,你确实让你确信默认的构造函数和它被调用后会发生一些缺省值。 您试图实现的是通用编译器功能及其创建,以检测未初始化变量的潜在误用,例如:
用于(int a;i除非定义了默认构造函数,否则定义之前的所有非静态变量都是未声明的。大多数基本类型都被视为基本类型,可以从C继承,并遵循C的体系结构-在这种情况下,编译器将确定大小,并在堆栈上分配此大小,仅此而已-底层内存是随机-或本身-未定义

如果是静态的,声明的变量如果未定义,则初始化为零 否则

所有非静态变量在声明它之前都被存储在内存段中,这可能导致<>强>未定义行为>极端情况下-信息泄漏。如果使用堆内存,最好在C++中调用CALLoc而不是MALOC,您确实可以确保存在默认构造。或者在被调用后进行一些默认操作

您试图实现的是通用编译器功能及其创建,以检测未初始化变量的潜在误用,例如:
对于(int a;我只是问,为什么你有两个
if(!err)
条件?我同意这非常烦人,对我来说很明显,“a”有一个有效的地址,它没有被取消引用,函数肯定会加载“a”。不确定如何告诉编译器,我也想知道如何:(10-20年前,未初始化变量的误报确实是GCC的一个问题,今天您必须编写一些非常复杂的代码来触发它们。这些警告中的大多数都是代码中真正正确的错误,值得偶尔对变量进行不必要的初始化来掩盖它们,以保持警告能够被捕获真正的错误。事实上,即使使用
静态内联
-O3
@Dummy00001,我也没有得到警告:那么你希望得到帮助来诊断我们无法重现的问题的原因吗?似乎是正确的。只是问一下,如果(!err)为什么你有两个
conditions?我同意这是非常烦人的,很明显“a”有一个有效地址,它没有被取消引用,函数肯定会加载“a”。我不知道如何告诉编译器,我也想知道如何:(10-20年前,未初始化变量的误报确实是GCC的一个问题,今天您必须编写一些非常复杂的代码来触发它们。这些警告中的大多数都是代码中真正正确的错误,值得偶尔对变量进行不必要的初始化来掩盖它们,以保持警告能够被捕获真正的错误。事实上,即使使用
静态内联
,以及
-O3
@Dummy00001,我也没有得到警告:所以你希望帮助诊断我们无法重现的问题的原因?似乎是合法的。你确实阅读了完整的问题及其注释,不是吗?确实,我忘了一些东西(编辑)我还记得一件事——试着用谷歌搜索一下gcc/g++翻译单元——如果您正在运行的函数在另一个翻译单元中,编译器可能无法检测到该函数正在变异参数,并向您发出警告。此外,这不是答案,但您可能会感兴趣,因为(1)未能阅读问题,(2)投反对票傲慢。在否决表决前阅读评论,我解释了解决问题的所有方法。没有强大的编译器设置可以超越翻译单元,因为编译器(1)不知道其他函数做什么,(2)编译时不要关心其他单元。要么将它们放在一个文件中,要么在使用前进行初始化。你确实阅读了完整的问题及其注释,不是吗?事实上,我忘记了一些(编辑)我记得的另一件事——试着在谷歌上搜索关于gcc/g++tr的信息
int func1()
{
    int err;
    int a;
    int b;  // *Edit1*

    err = func2( &a ); // init 'a' or fail with 'err'
    if (!err)
    {
        b = 1; // *Edit1*
    }

    if (!err)
    {
        // use variable 'a'
        // here compiler migth produce warning that 'a' might be uninitialized
    }

    if (!err) // *Edit1*
    {
        // use variable 'b'
        // here compiler might produce warning that 'b' might be uninitialized
    }

    return err;
}
int err = 0;
int a   = 0;
int b   = 0;

err = func2( &a ); // no warnings
if (!err) b = 1;
if (!err) err = stuff(a);
if (!err) err = stuff(b)

return err;
somecomplextype * x = (somecomplextype) calloc (1, sizeof(somecomplextype));
if (!x) exit(1);