3

我正在阅读FreeBSD 编码风格并且非常喜欢它(因为我喜欢垂直紧凑的代码)。然而有这样的:

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

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

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


为了澄清,为了回应abasu的评论,我的例子试图说明没有可用的无效值的情况。我问了一个问题,得到的回答是使用不可能的值来标记错误或其他条件非常棒。但情况并非总是如此。例子很多: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

4 回答 4

5

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

如果不是,则使用无效值来初始化personal_number.

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

当然,在这两种情况下,最好不要使用整数文字进行初始化,而是执行以下操作:

enum { INVALID_PERSONAL_NUMBER = -1 }

int personal_number = INVALID_PERSONAL_NUMBER;
于 2013-05-10T09:24:00.163 回答
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;
}

优化编译器会推断出不可能nameNULL消除检查。类似的问题导致了安全漏洞;参见例如http://blog.llvm.org/2011/05/what-every-c-programmer-should-know_14.html

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

于 2013-05-10T09:32:33.893 回答
1

当一个变量没有合适的初始值时,让它没有值不是更好吗?

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

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

于 2013-05-10T10:59:02.383 回答
0

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

未初始化的变量将包含一些垃圾值。如果您没有初始化它并且错误地尝试使用它。你可能会得到一些意想不到的结果。例如:

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

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

在大型程序的情况下,这种情况会变得很严重,这些类型的失误很常见。所以为了避免愚蠢的错误,否则可能会在调试它们时花费大量时间,变量应该总是被初始化

于 2013-05-10T09:56:54.173 回答