C 始终初始化所有变量

C 始终初始化所有变量,c,coding-style,C,Coding Style,我正在阅读并且非常喜欢它(因为我喜欢垂直压缩的代码)。然而,有一点是: 初始化所有变量 您应始终初始化变量。总是。每一次。带有-W标志的gcc可以捕获对未初始化变量的操作,但 也可能不是 理由 比您想象的更多的问题最终可以追溯到未初始化的指针或变量 当一个变量没有合适的初始值时,让它没有值不是更好吗。这样,编译器可能会捕获未初始化的读取。我不是说T*p=NULL,这是一种陷阱表示,可能(也可能不是)非常有用,而是说int personal_number=0/*但是0是一个有效的个人数字*/ 为

我正在阅读并且非常喜欢它(因为我喜欢垂直压缩的代码)。然而,有一点是:

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

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

当一个变量没有合适的初始值时,让它没有值不是更好吗。这样,编译器可能会捕获未初始化的读取。我不是说
T*p=NULL
,这是一种陷阱表示,可能(也可能不是)非常有用,而是说
int personal_number=0/*但是0是一个有效的个人数字*/


为了澄清,针对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);
这样,如果忘记初始化,将出现警告,错误将被修复,删除警告。

所有整数都是有效的个人数字吗

如果不是,则使用无效值初始化
个人\u号码

如果是,那么即使您自己没有初始化
personal\u number
它仍然保存一个有效的个人号码值,但该值是未知的。因此,不管怎样,将其初始化为
0
——您没有引入问题(之前的有效数字,之后的有效数字),唯一的区别是您现在知道了该数字

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

enum { INVALID_PERSONAL_NUMBER = -1 }

int personal_number = INVALID_PERSONAL_NUMBER;

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

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
,并消除检查。类似的问题导致了安全漏洞;见例


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

初始化变量总是很有用的,也是一种很好的编码实践。 这可以通过以下示例理解:

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

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

    //You didn't initialize a  
    if(a > 10) 
    {
          //Unpredicted result
    }
    else{}
    return 0;
}
如果有更大的项目,情况会变得更严重,这些类型的失误很常见。 因此,为了避免愚蠢的错误,否则可能会在调试过程中花费大量时间,应该始终初始化变量

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

在我看来是的。现代编译器非常擅长捕捉未初始化的变量错误,而叮当作响的静态分析器近乎完美。让编译器捕捉到问题要比输入会导致运行时问题的内容好得多。例如,将指针初始化为NULL将抑制编译器警告,但在尝试取消引用时不会停止核心转储


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

取决于什么是合理的。。。将
-1
作为无效的
个人号码如何?如果它也未初始化,则并不意味着没有值。该值也可以是一个有效数字(偶然,意外)。那么你的选择是什么呢?如果一个未初始化的变量有一些有效的值,会产生一些不必要的副作用,那么这会让它走运,并可能面临灾难吗?或者花10秒钟找出一个无效的值,并确保您的变量已初始化(当然,您的程序正在检查该值)@abasu,我的观点是编译器或静态分析器将很容易检测到未初始化的值。另一方面,将变量设置为错误的有效值可能会使程序员和机器混淆。@Vorac Ok。编译器将捕获未初始化的文件并向您发出警告。这太棒了。那你怎么办?“始终初始化变量”与利用编译器警告并不矛盾。实际上,警告的存在首先是因为您违反了规则。问题是你将如何纠正这种违规行为。或者,您是否在代码中看到警告,您使用未初始化的变量只是为了看到警告?如果你不采取措施,那就没有意义了。@Vorac是的,你的观点是正确的。(虽然我不确定,编译器和静态分析器可以捕获100%的情况,因此,有运行时工具)但第二行,
将变量设置为错误的有效值
不是错误(即编码错误??)。如果是,则可能会出现混淆。预期的不是问题,问题是意外的。:)(个人经验)假设变量存在无效值(因为我的示例不好)。有些情况下,情况并非如此。我对他们很感兴趣。@Vorac他没有假设任何事情。他给了你我认为在这两种情况下最好的答案:如果不是(…),如果