提问人:just Impartial 提问时间:7/5/2023 最后编辑:Jan Schultkejust Impartial 更新时间:7/6/2023 访问量:137
立即初始化变量在 C++ 中很重要
Is immediately initializing a variable important in C++
问:
我最近读了一本编程书。它说如果我们在初始化变量时没有给出值,如下例所示:
int i;
int i {0};
...那么它有时可能会导致运行时错误。但是,我不确定这是否正确。未初始化的变量会设置为随机整数吗?为什么这会导致运行时错误?
我还没有遇到过这种运行时错误。为变量提供 init 值重要吗?
答:
在 C++ 中,默认情况下不会初始化函数作用域中的非静态变量(函数内部,也称为局部变量)或没有任何其他初始化的类成员变量。它们将具有不确定的值。以任何方式使用不确定的值都会导致未定义的行为。
除非您使用的是未初始化的指针,否则不太可能发生崩溃(尽管某些浮点值可能会导致异常)。纯整数只会给你带来意想不到的结果。
综上所述,如果您计划稍后(但在使用其值之前)为它们赋值,则不必显式初始化所有局部变量。
在函数或类之外定义的变量将被初始化。将其值设置为零(或类型的相应值,即指针变为 null 指针)。
static
局部变量和成员变量也将初始化值。
评论
是的,这本书是对的。通常建议始终在声明变量后立即初始化变量。原因是从未初始化的变量中读取会调用未定义的行为。
此代码
int evil;
std::cout << evil;
在调试版本中可能看起来不错。在调试版本中,编译器执行的操作超出了其需要。它可能会为您进行初始化。不过,在调试版本中,编译器的作用也比在发布版本中少:它不应用优化。它不会像在发布版本中那样分析您的代码并对其进行转换以获得更好的性能。这就是为什么上面的代码在调试版本中看起来很好,而在发布版本中可能会发生不好的事情。
假设您知道您不被允许从未初始化的变量中读取,并且您写道:
int ok;
ok = 42;
std::cout << ok;
然后一切都很好。但是,通常代码看起来并不那么简单。它看起来像这样:
int notok;
if (some_condition) {
notok = 42;
} else {
std::cout << "hello world";
}
std::cout << notok;
很容易意外使用尚未初始化的变量。因此,建议始终初始化它们:
int good = 42;
评论
ok
不是未初始化的。它是默认初始化的。它的生命周期已经开始(这就是为什么可以稍后分配它),但它的值是不确定的。
感谢您上面的回复。我写了一些代码,并在我的计算机(linux 6.2.0-24-generic)中以不同的优化级别运行测试。结果如下:
❯ g++ varinit.cpp -o varinito3 -O3
g++ varinit.cpp -o varinito2 -O2
g++ varinit.cpp -o varinito1 -O1
g++ varinit.cpp -o varinito0 -O0
❯ ./varinito3
0
❯ ./varinito2
0
❯ ./varinito1
0
❯ ./varinito0
32766
❯ icpx varinit.cpp
❯ ./a.out
-1884400440
我注意到在优化构建 (G++) 中,int 变量将默认初始化为零,但在无优化编译中,默认值为随机常量(运行它时不会随时间变化)。此外,在英特尔 cpp 编译器 (icpx) 中,该值是随机的,但每次编译时都会发生变化。
评论