为什么 `main` 函数中的局部 int 变量会自动初始化?
Why local int variables inside `main` function will be initialized automatically?
我是 C++ 新手,在学习 C++ 时遇到了这个问题。
这是代码
#include <iostream>
using namespace std;
void another_func() {
int a;
cout << a << endl;
}
int main() {
int a;
cout << a << endl;
another_func();
}
我正在使用 g++ (GCC) 10.1.0
,我发现每次 运行 代码时, main
函数中的 a
都会初始化为 0
,而 another_func
中的 a
将是一个随机数。如下,
➤ g++ test.cpp && ./a.out
a in main: 0
a in another_func: 32612
据我所知,局部变量存储在堆栈中,它们没有自动初始化机制。因此 another_func
中的 a
是预期的。但是,有人能告诉我为什么 main
函数中的 a
被初始化为 0
吗?
提前致谢!
标准不要求局部变量的默认零值,但一些编译器可能会进行零初始化
只有 global
个变量和 static
个成员必须初始化为零,除非另外明确初始化。
未初始化并不意味着非零,它可以有任何值。在许多操作系统上,新分配的内存页被 0
填充,因此在非调试代码中,未初始化的值通常也是 0
。
你的程序的行为是未定义的,但可能发生的是 main
中的 a
是堆栈的第一次使用,或者你只是幸运并且之前运行的初始化代码main
离开堆栈的那个区域 0
。
对 cout
的调用将写入堆栈,因此当您随后执行 another_func
时,堆栈内存将不再全部 0
。
tl;dr:您不能读取未初始化的值。
两个 a
都没有初始化为任何东西。这意味着它们有一个不确定的值,可以是包括 0 在内的任何值。任何推理都必须到此为止,因为 读取未初始化的值会调用未定义的行为 (UB)。
UB意味着一切皆有可能。您的程序无效,您不再有任何保证。不允许您读取 a
,因此推理为什么您可能会在特定情况下读取特定值没有用。
这就是C++语言的观点。对于编写 C++ 程序,您通常需要自己采纳这种观点。当然有一个编译器参与。更具体地说,具有特定配置的特定版本的特定编译器为特定平台编译这段代码。包括所有这些,您 可以 对您看到特定结果的原因进行一些调查。如果您对编译器的工作原理感兴趣,那将是一件很有用的事情。但它很少有助于编写程序。更改编译器标志或使用稍微不同的代码,结果可能会有所不同。
我是 C++ 新手,在学习 C++ 时遇到了这个问题。
这是代码
#include <iostream>
using namespace std;
void another_func() {
int a;
cout << a << endl;
}
int main() {
int a;
cout << a << endl;
another_func();
}
我正在使用 g++ (GCC) 10.1.0
,我发现每次 运行 代码时, main
函数中的 a
都会初始化为 0
,而 another_func
中的 a
将是一个随机数。如下,
➤ g++ test.cpp && ./a.out
a in main: 0
a in another_func: 32612
据我所知,局部变量存储在堆栈中,它们没有自动初始化机制。因此 another_func
中的 a
是预期的。但是,有人能告诉我为什么 main
函数中的 a
被初始化为 0
吗?
提前致谢!
标准不要求局部变量的默认零值,但一些编译器可能会进行零初始化
只有 global
个变量和 static
个成员必须初始化为零,除非另外明确初始化。
未初始化并不意味着非零,它可以有任何值。在许多操作系统上,新分配的内存页被 0
填充,因此在非调试代码中,未初始化的值通常也是 0
。
你的程序的行为是未定义的,但可能发生的是 main
中的 a
是堆栈的第一次使用,或者你只是幸运并且之前运行的初始化代码main
离开堆栈的那个区域 0
。
对 cout
的调用将写入堆栈,因此当您随后执行 another_func
时,堆栈内存将不再全部 0
。
tl;dr:您不能读取未初始化的值。
两个 a
都没有初始化为任何东西。这意味着它们有一个不确定的值,可以是包括 0 在内的任何值。任何推理都必须到此为止,因为 读取未初始化的值会调用未定义的行为 (UB)。
UB意味着一切皆有可能。您的程序无效,您不再有任何保证。不允许您读取 a
,因此推理为什么您可能会在特定情况下读取特定值没有用。
这就是C++语言的观点。对于编写 C++ 程序,您通常需要自己采纳这种观点。当然有一个编译器参与。更具体地说,具有特定配置的特定版本的特定编译器为特定平台编译这段代码。包括所有这些,您 可以 对您看到特定结果的原因进行一些调查。如果您对编译器的工作原理感兴趣,那将是一件很有用的事情。但它很少有助于编写程序。更改编译器标志或使用稍微不同的代码,结果可能会有所不同。