始终初始化所有变量

时间:2013-05-10 09:19:00

标签: c coding-style

我正在阅读the FreeBSD coding style并且非常喜欢它(因为我喜欢垂直紧凑的代码)。但是有这个:

  

初始化所有变量
  你应该总是初始化变量。总是。每次。带有标志-W的gcc可以捕获未初始化变量的操作,但是   它也可能没有。

     

理由
  比你想象的更多的问题最终会追溯到未初始化的指针或变量。

如果变量没有合适的初始值,那么在没有值的情况下保留它是不是更好。这样编译器可能会在未初始化的情况下读取它。我不是在谈论T *p = NULL,这是一个陷阱表示,可能(或可能不是)非常有用,而是int personal_number = 0 /* but 0 is a valid personal number!!*/


为了澄清,为了回应 abasu 的评论,我的示例是试图说明没有可用无效值时的情况。我问过question,并回答说使用不可能的值来标记错误或其他条件非常棒。但情况并非总是如此。例子很多:8位像素值,速度矢量等


“始终初始化变量”的一个有效替代方法,我可以看到:

//logical place for declarations
T a;

/*code, for example to set up the environment for evaluating a*/

a = fooForA();

/*more code*/

fooThatUsesA(a);

这样一来,如果忘记了初始化,就会出现警告并修复错误,删除警告。

4 个答案:

答案 0 :(得分:4)

所有整数都是有效的个人号码吗?

如果没有,则使用无效值初始化personal_number

如果是,那么即使您没有自己初始化personal_number ,它仍然拥有一个有效的个人号码 - 但该值未知。所以无论如何将它初始化为0 - 你没有引入问题(之前的有效数字,之后的有效数字),唯一的区别是这个数字现在已为您所知。

当然,在这两种情况下,最好不要使用整数文字进行初始化,而是做类似的事情:

enum { INVALID_PERSONAL_NUMBER = -1 }

int personal_number = INVALID_PERSONAL_NUMBER;

答案 1 :(得分:2)

编译器通常不会捕获未初始化的读取变量。相反,他们可能会使用该信息来对其余代码进行假设以执行优化,可能会引入新的和更糟糕的错误:

int get_personal_number(const char *name)
{
    int personal_number;
    if (name != NULL) {
        /* look up name in some array */
        personal_number = ...
    }
    return personal_number;
}

优化编译器将推断 name不能NULL并取消检查。类似的问题也导致了安全漏洞;见例如http://blog.llvm.org/2011/05/what-every-c-programmer-should-know_14.html

相反,重写您的函数以在声明时初始化变量及其最终正确值;这可能需要编写许多小函数,使用三元表达式等,这通常是更好的风格。

答案 2 :(得分:1)

  

如果变量没有合适的初始值,那么在没有值的情况下保留它是不是更好。

在我看来是的。现代编译器非常擅长捕获未初始化的变量错误,并且clang静态分析器几乎完美无缺。让编译器捕获问题比放入会导致运行时问题的问题要好得多。例如,将指针初始化为NULL将禁止编译器警告,但是当您尝试取消引用它时,它不会停止核心转储。

但是,如果您使用的是现代编译器,那么您可能正在使用C99,这意味着您不需要声明变量,直到您知道它的合理值。这就是我要做的事。

答案 3 :(得分:0)

初始化变量总是很有用,并且是一种很好的编码实践。 这个例子可以理解:

未初始化的变量将包含一些垃圾值。如果你没有初始化它,那么你试图使用它。你可能得到一些不可预知的结果。 例如:

int test(void)
{
    int a; //uninitialized variable

    //You didn't initialize a  
    if(a > 10) 
    {
          //Unpredicted result
    }
    else{}
    return 0;
}

如果程序较大,这些类型的遗漏很常见,情况就会变得严峻。 因此,为了避免在调试时可能会耗费大量时间的愚蠢错误,应始终初始化变量