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



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

int x = 5; // definition with initialisation

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

int x; // uninitialised definition

为什么C++编译器在全局变量和作用域变量的初始值方面行为不同。

这是根本性的吗?

命名空间

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

C++标准 (n3242( 中的 §3.6.2/2 说:

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

对于具有自动存储持续时间的局部变量,标准对编译器没有这样的要求。因此,出于性能原因,自动变量通常未初始化 — 几乎所有主要编译器都选择这种方法,尽管可能有一个编译器也可以初始化自动变量。

"为每个定义的整数保留一个四字节内存插槽。

不,不是。忽略"4 字节"大小,该语句的主要问题是现代编译器每次分配给变量时通常会找到一个新位置。这可以是寄存器或内存中的某个位置。这涉及到很多聪明。

未初始化的变量不会写入,因此通常甚至没有为其分配位置。尝试读取"it"可能根本不会产生值;编译器可能会直接失败,无法为此生成代码。

现在全局是另一回事。由于可以从任何地方读取和写入它们,因此编译器不能在每次写入时为它们找到新位置。他们必须坚持一个地方,而且实际上不可能是一个登记册。通常,它们都分配给一个内存块中。将该块归零通常可以非常有效地完成。这就是为什么全局变量是不同的。

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

堆栈

空间通常只需调整堆栈指针即可"分配"。如果函数中有 32 个字节的简单变量,则编译器会发出等效于 "sp = sp - 32" 的指令这些变量的任何初始化都需要额外的代码和执行时间 - 因此它们最终被初始化为明显的随机值。

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

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

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

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

最新更新