C++ 为什么全局变量和静态变量被初始化为其默认值?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2091499/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why are global and static variables initialized to their default values?
提问by Xinus
In C/C++, why are globals and static variables initialized to default values?
在 C/C++ 中,为什么将全局变量和静态变量初始化为默认值?
Why not leave it with just garbage values? Are there any special reasons for this?
为什么不只留下垃圾值呢?这有什么特殊原因吗?
回答by DigitalRoss
Security: leaving memory alone would leak information from other processes or the kernel.
Efficiency: the values are useless until initialized to something, and it's more efficient to zero them in a block with unrolled loops. The OS can even zero freelist pages when the system is otherwise idle, rather than when some client or user is waiting for the program to start.
Reproducibility: leaving the values alone would make program behavior non-repeatable, making bugs really hard to find.
Elegance: it's cleaner if programs can start from 0 without having to clutter the code with default initializers.
安全性:单独留下内存会泄漏来自其他进程或内核的信息。
效率:这些值在初始化为某些东西之前是无用的,并且在具有展开循环的块中将它们归零更有效。操作系统甚至可以在系统空闲时将空闲列表页面归零,而不是在某些客户端或用户等待程序启动时。
可重复性:单独保留这些值会使程序行为不可重复,从而使错误很难发现。
优雅:如果程序可以从 0 开始,而不必使用默认初始值设定项来弄乱代码,那就更干净了。
One might then wonder why the auto
storage class doesstart as garbage. The answer is two-fold:
那么有人可能会问,为什么auto
存储类并启动垃圾。答案有两个:
It doesn't,in a sense. The very first stack frame page at each level (i.e., every new page added to the stack) does receive zero values. The "garbage", or "uninitialized" values that subsequent function instances at the same stack level see are really the previous values left by other method instances of your own program and its library.
There might be a quadratic (or whatever) runtime performance penaltyassociated with initializing
auto
(function locals) to anything. A function might not use any or all of a large array, say, on any given call, and it could be invoked thousands or millions of times. The initialization of statics and globals, OTOH, only needs to happen once.
从某种意义上说,它不会。每个级别的第一个堆栈框架页面(即添加到堆栈的每个新页面)确实接收零值。相同堆栈级别的后续函数实例看到的“垃圾”或“未初始化”值实际上是您自己的程序及其库的其他方法实例留下的先前值。
可能存在与初始化(函数局部变量)相关联的二次(或其他)运行时性能损失
auto
。一个函数可能不会使用任何或所有大数组,比如说,在任何给定的调用中,它可能被调用数千或数百万次。静态变量和全局变量 OTOH 的初始化只需要发生一次。
回答by R Samuel Klatchko
Because with the proper cooperation of the OS, 0 initializing statics and globals can be implemented with no runtime overhead.
因为在操作系统的适当配合下,可以在没有运行时开销的情况下实现 0 初始化静态和全局变量。
回答by Jingguo Yao
Section 6.7.8 Initialization of C99 standard (n1256) answers this question:
第 6.7.8 节 C99 标准 (n1256) 的初始化回答了这个问题:
If an object that has automatic storage duration is not initialized explicitly, its value is indeterminate. If an object that has static storage duration is not initialized explicitly, then:
如果没有显式初始化具有自动存储持续时间的对象,则其值是不确定的。如果没有显式初始化具有静态存储持续时间的对象,则:
— if it has pointer type, it is initialized to a null pointer;
——如果是指针类型,则初始化为空指针;
— if it has arithmetic type, it is initialized to (positive or unsigned) zero;
——如果它有算术类型,它被初始化为(正或无符号)零;
— if it is an aggregate, every member is initialized (recursively) according to these rules;
— 如果是聚合,则根据这些规则(递归地)初始化每个成员;
— if it is a union, the first named member is initialized (recursively) according to these rules.
— 如果是联合,则根据这些规则(递归地)初始化第一个命名成员。
回答by Charles Eli Cheese
Think about it, in the static realm you can't tell always for sure something is indeed initialized, or that main has started. There's also a static init and a dynamic init phase, the static one first right after the dynamic one where order matters.
想一想,在静态领域中,您不能总是确定确实已初始化某些内容,或者该 main 已启动。还有一个静态初始化阶段和一个动态初始化阶段,静态阶段在动态阶段之后,顺序很重要。
If you didn't have zeroing out of statics then you would be completely unable to tell in this phase for sure if anything was initialized AT ALL and in short the C++ world would fly apart and basic things like singletons (or any sort of dynamic static init) would simple cease to work.
如果您没有将静态归零,那么在此阶段您将完全无法确定是否有任何东西被初始化,简而言之,C++ 世界将分崩离析,基本事物如单例(或任何类型的动态静态init) 将简单地停止工作。
The answer with the bulletpoints is enthusiastic but a bit silly. Those could all apply to nonstatic allocation but that isn't done (well, sometimes but not usually).
要点的答案很热情,但有点傻。这些都可以适用于非静态分配,但这还没有完成(好吧,有时但不通常)。
回答by Anant Simran Singh
In C, statically-allocated objects without an explicit initializer are initialized to zero (for arithmetic types) or a null pointer (for pointer types). Implementations of C typically represent zero values and null pointer values using a bit pattern consisting solely of zero-valued bits (though this is not required by the C standard). Hence, the bss section typically includes all uninitialized variables declared at file scope (i.e., outside of any function) as well as uninitialized local variables declared with the static keyword.
在 C 中,没有显式初始化程序的静态分配对象被初始化为零(对于算术类型)或空指针(对于指针类型)。C 的实现通常使用仅由零值位组成的位模式表示零值和空指针值(尽管这不是 C 标准所要求的)。因此,bss 部分通常包括在文件范围(即,在任何函数之外)声明的所有未初始化变量以及使用 static 关键字声明的未初始化局部变量。
Source: Wikipedia
资料来源:维基百科