在我正在编写的程序中,我的.h文件中有几个未初始化的变量,所有这些变量在运行时初始化。然而,在Visual Studio中,每当我这样做时,它会警告我“始终初始化成员变量”,尽管这似乎毫无意义。我很清楚,在未初始化变量时尝试使用它将导致未定义的行为,但据我所知,这可以通过不这样做来避免。我是否忽略了什么?
谢谢。
谢谢。
这个问题有两个部分:第一个是读取未初始化的变量是否危险,第二个是定义未初始化的变量是否危险,即使我确保从未访问过未初始化的变量。
除了极少数例外,访问未初始化的变量会导致整个程序出现未定义行为。有一个常见的误解(不幸的是被教授),即未初始化的变量具有“垃圾值”,因此读取未初始化的变量将导致读取某些值。这是完全错误的。未定义行为意味着程序可以具有任何行为:它可能会崩溃,它可能会表现为变量具有某个值,它可能会假装变量甚至不存在或者出现各种奇怪的行为。
例如:
void foo();
void bar();
void test(bool cond)
{
int a; // uninitialized
if (cond)
{
a = 24;
}
if (a == 24)
{
foo();
}
else
{
bar();
}
}
调用上述函数时,使用true
的结果是什么?使用false
呢?
test(true)
将明确调用foo()
。
那么test(false)
呢?如果你回答:“这取决于变量a
中的垃圾值是什么,如果它是24
,它将调用foo
,否则它将调用bar
”,那么你完全错了。
如果你调用test(false)
,程序将访问未初始化的变量,并具有未定义的行为,这是一条非法路径,因此编译器可以自由地假设cond
永远不会是false
(否则程序将是非法的)。而且,令人惊讶的是,启用优化的gcc和clang实际上都这样做,并生成此汇编函数:
test(bool):
jmp foo()
所以不要这样做!永远不要访问未初始化的变量!这是未定义的行为,比“变量具有一些垃圾值”更糟糕。此外,在您的系统上可能按预期工作,在其他系统或使用其他编译器标志时,它可能表现出意外的方式。
好吧,从这个角度来看,程序是正确的,但源代码容易出错。你必须时刻注意检查是否实际上初始化了变量。如果你忘记初始化一个变量,找到 bug 将很困难,因为你的代码中有很多定义未初始化的变量。
相反,如果你总是初始化你的变量,你和后来的程序员都会轻松得多。
这只是一种非常非常好的实践。