C++ 全局和作用域整数初始值

问题描述 投票:0回答:3

为每个定义的整数保留四字节内存槽。未初始化的变量保留该槽的旧值。因此,初始值在某种程度上是随机的。

int x = 5; // definition with initialisation

据我所知,这一事实在大多数 C++ 编译器中都适用于作用域变量。但是,当涉及到全局变量时。将设置零值。

int x; // uninitialised definition

为什么 C++ 编译器对于全局变量和作用域变量的初始值表现不同。

这是基础吗?

c++ initialization global-variables
3个回答
4
投票

命名空间级别变量(即全局)属于static存储持续时间,根据标准,所有具有静态存储持续时间的变量都是静态初始化的,这意味着所有位都设置为0:

C++ 标准 (n3242) 中的

§3.6.2/2 说,

具有静态存储持续时间(3.7.1)或线程存储持续时间(3.7.2)的变量应在进行任何其他初始化之前进行零初始化(8.5)。

对于具有“自动”存储期限的局部变量,标准对编译器施加“无”这样的要求。因此,出于性能原因,自动变量通常未初始化 - 几乎所有主要编译器都选择这种方法,尽管可能有一个编译器也会初始化 automatic 变量。

“为每个定义的整数保留四个字节的内存槽。”

2
投票

不,不是。忽略“4 字节”大小,该语句的主要问题是现代编译器通常在每次分配变量时都会为变量找到一个新位置。这可以是寄存器或内存中的某个位置。这涉及到很多智慧。 未初始化的变量不会被写入,因此通常甚至没有为其分配位置。尝试读取“it”可能根本不会产生任何价值;编译器可能会完全无法生成代码。

现在全局变量是另一回事了。由于可以从任何地方读取和写入它们,因此编译器不能在每次写入时为它们找到新的位置。它们必须固定在一个地方,而它实际上不可能是一个寄存器。通常它们都一起分配在一块内存中。通常可以非常有效地将该块清零。这就是全局变量不同的原因。

正如您所料,这种行为背后也有效率驱动的原因。


1
投票

全局变量完全是另一头野兽。 简单变量由程序加载器有效分配,并且可以位于通常所说的“BSS”中。这些变量在可执行文件中几乎不占用任何空间。所有这些都可以合并到一个块中 - 因此可执行映像只需要指定块的大小。由于操作系统必须确保新进程不会看到内存中某些已死亡进程的任何剩余数据,因此内存需要填充一些东西 - 你也可以用零填充它。

初始化为非零的全局变量实际上确实占用了可执行文件中的空间,它们显示为数据块并且只是加载到内存中 - 可执行文件中没有代码来初始化它们。

C++ 还允许需要执行代码来初始化的全局变量,C 不允许这样做。 例如“int x = rand();” 在运行时通过可执行文件中的代码进行初始化。

尝试添加这个全局变量 int x[1024 * 1024]; 并查看它是否对可执行文件大小产生影响。 现在尝试: int x[1024 * 1024] = {1,2,3}; 看看有什么不同。

© www.soinside.com 2019 - 2024. All rights reserved.