C++ 为什么局部变量不设为零?

C++ 为什么局部变量不设为零?,c++,c,C++,C,既然默认情况下全局变量和静态变量都初始化为0,为什么局部变量默认情况下也不初始化为0?因为这需要时间,而且并不总是需要它们为零 局部变量的分配(通常在CPU的硬件堆栈上)非常快,远远少于每个变量一条指令,并且基本上与变量的大小无关 因此,与分配相比,任何初始化代码(通常不独立于变量的大小)都会增加相对大量的开销,而且由于您无法确定是否需要初始化,因此在优化性能时会造成很大的中断 全局/静态变量是不同的,它们通常存在于程序二进制文件的某个段中,该段由程序加载器设置为0,因此您可以“免费”获得该值。

既然默认情况下全局变量和静态变量都初始化为0,为什么局部变量默认情况下也不初始化为0?

因为这需要时间,而且并不总是需要它们为零

局部变量的分配(通常在CPU的硬件堆栈上)非常快,远远少于每个变量一条指令,并且基本上与变量的大小无关

因此,与分配相比,任何初始化代码(通常不独立于变量的大小)都会增加相对大量的开销,而且由于您无法确定是否需要初始化,因此在优化性能时会造成很大的中断


全局/静态变量是不同的,它们通常存在于程序二进制文件的某个段中,该段由程序加载器设置为0,因此您可以“免费”获得该值。

全局和静态变量存储在数据段中[在程序开始执行之前,内核将未初始化数据段中的数据初始化为算术0],而局部变量存储在调用堆栈中。

这是因为全局变量和静态变量位于与局部变量不同的内存区域

  • 未初始化的静态和全局变量存在于.bss段中,该段是一个内存区域,保证在程序启动时,在程序进入“main”之前初始化为零

  • 显式初始化的静态和全局变量是实际应用程序文件的一部分,它们的值在编译时确定,并与应用程序一起加载到内存中

  • 局部变量在运行时通过增长堆栈动态生成。如果堆栈增长到包含垃圾的内存区域,则未初始化的局部变量将包含垃圾(垃圾输入、垃圾输出)


因为这种零初始化需要执行时间。这会使您的程序大大降低速度。每次调用函数时,程序都必须执行无意义的开销代码,这会将变量设置为零

静态变量在程序的整个生命周期中都会持续存在,因此您可以在那里为零初始化静态变量,因为它们只初始化一次,而局部变量在运行时初始化


在实时系统中,启用一个编译器选项来停止静态存储对象的零初始化也是很常见的。这样的选项使程序成为非标准的,但也使其启动更快。

主要是历史性的。早在定义C时,零 静态变量的初始化由 操作系统,并且无论如何都会发生,其中作为零初始化 局部变量的定义需要运行时 今天在许多系统(包括所有Unix和Windows)上都是如此。 然而,第二个问题要小得多;大多数编译器都会这样做 在大多数情况下检测多余的初始化,并跳过它, 如果编译器不能这样做,那么 代码将非常复杂,需要足够的时间 初始化将无法测量。您仍然可以 构建特殊情况,但情况并非如此 它们当然非常罕见。然而,原来的C是 没有一个委员会进行过审查
问题自。

由您显式初始化的全局或静态变量将存储在.data段(初始化数据)中,而未初始化的全局或静态变量将存储在.bss(未初始化数据)中

此.bss未存储在编译的.obj文件中,因为这些变量没有可用数据(请记住,您没有使用任何特定数据初始化它们)

现在,当操作系统加载exe时,它只会查看.bss段的大小,分配那么多内存,然后zero为您初始化它(
exec
)。这就是为什么需要将.bss段初始化为零


局部变量没有初始化,因为不需要初始化它们。它们存储在堆栈级别,因此加载exe将自动加载局部变量所需的内存量。那么,为什么要对局部变量进行额外初始化,使我们的程序变慢呢。

假设您需要调用函数100次,如果有局部变量,假设它是 要每次初始化为0…哎呀,会有额外的开销和时间浪费。
另一方面,全局变量只初始化一次。因此,我们可以将其默认值初始化为0。< /P>因为这要花费一些东西。参见,因为语言标准表示。@ JoachimPileborg。C中的定义表示,它们初始化为值“代码> 0 < /C>”,转换为正确的类型。C++使用相同的类型。基本类型的定义(以及其他类型的递归)。当然,这并不意味着所有的0位,因为类型转换可能会改变位模式,但这是“初始化为0”的一种解释。这个例子不是很好,有两个原因。首先,任何值得一试的编译器都会检测到,抑制原始初始化不会改变代码的可观察行为,并且会这样做;其次,如果实际的初始化成本很高,那么零初始化与之相比就不太明显。@JamesKanze Fine,我删除了该示例。谢谢。@JamesKanze,但假设循环条件不是编译时常量,而是运行时常量。那么编译器就不能真正进行优化。@Lundin这取决于情况。如果您从未访问元素,编译器可以看到这一点,而不是初始化。导致编译器问题的实际情况是您执行了类似于
int-array[10000];initializeArray(array,10000);
,w的操作