C语言 为什么静态变量自动初始化为零?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3373108/
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 static variables auto-initialized to zero?
提问by j riv
Possible Duplicate:
Why global and static variables are initialized to their default values?
可能的重复:
为什么全局和静态变量被初始化为它们的默认值?
What is the technical reason this happens? And is it supported by the standard across all platforms? Is it possible that certain implementations may return undefined variables if static variables aren't explicitly initialized?
发生这种情况的技术原因是什么?它是否受所有平台的标准支持?如果未显式初始化静态变量,某些实现是否可能返回未定义的变量?
回答by Jerry Coffin
It isrequired by the standard (§6.7.8/10).
这是标准 (§6.7.8/10) 所要求的。
There's no technical reason it would haveto be this way, but it's been that way for long enough that the standard committee made it a requirement.
没有技术上的理由必须这样,但这种方式已经存在了足够长的时间,以至于标准委员会将其作为一项要求。
Leaving out this requirement would make working with static variables somewhat more difficult in many (most?) cases. In particular, you often have some one-time initialization to do, and need a dependable starting state so you know whether a particular variable has been initialized yet or not. For example:
在许多(大多数?)情况下,忽略此要求会使使用静态变量变得更加困难。特别是,您经常需要进行一些一次性初始化,并且需要一个可靠的起始状态,以便您知道某个特定变量是否已被初始化。例如:
int foo() {
static int *ptr;
if (NULL == ptr)
// initialize it
}
If ptrcould contain an arbitrary value at startup, you'd have to explicitly initialize it to NULL to be able to recognize whether you'd done your one-time initialization yet or not.
如果ptr在启动时可以包含任意值,则必须将其显式初始化为 NULL 才能识别是否已完成一次性初始化。
回答by nmichaels
Yes, it's because it's in the standard; but really, it's because it's free. Static variables look just like global variables to the generated object code. They're allocated in .bss and initialized at load time along with all your constants and other globals. Since the section of memory where they live is just copied straight from your executable, they're initialized to a value known at compile-time for free. The value that was chosen is 0.
是的,这是因为它在标准中;但实际上,这是因为它是免费的。对于生成的目标代码,静态变量看起来就像全局变量。它们在 .bss 中分配并在加载时与所有常量和其他全局变量一起初始化。由于它们所在的内存部分是直接从您的可执行文件中复制的,因此它们会被免费初始化为编译时已知的值。选择的值为 0。
回答by Amardeep AC9MF
Of course there is no arguing that it is in the C standards. So expect a compliant compiler to behave that way.
当然,没有争论说它在 C 标准中。因此,期望兼容的编译器以这种方式行事。
The technical reason behind why it was done mightbe rooted in how the C startup code works. There are usually several memory segments the linker has to put compiler output into including a code (text) segment, a block storage segment, and an initialized variable segment.
其背后的技术原因可能源于 C 启动代码的工作方式。链接器通常必须将编译器输出放入多个内存段,包括代码(文本)段、块存储段和初始化变量段。
Non-static function variables don't have physical storage until the scope of the function is created at runtime so the linker doesn't do anything with those.
在运行时创建函数的作用域之前,非静态函数变量没有物理存储,因此链接器不会对这些变量执行任何操作。
Program code of course goes in the code (or text) segment but so do the valuesused to initialize global and static variables. Initialized variables themselves (i.e. their addresses) go in the initialized memory segment. Uninitialized global and static variables go in the block storage (bss) segment.
程序代码当然在代码(或文本)段中,但用于初始化全局和静态变量的值也是如此。初始化变量本身(即它们的地址)进入初始化的内存段。未初始化的全局和静态变量进入块存储 (bss) 段。
When the program is loaded at execution time, a small piece of code creates the C runtime environment. In ROM based systems it will copy the valueof initialized variables from the code (text) segment into their respective actual addresses in RAM. RAM (i.e. disk) based systems can load the initial values directly to the final RAM addresses.
在执行时加载程序时,一小段代码创建了 C 运行时环境。在基于 ROM 的系统中,它会将初始化变量的值从代码(文本)段复制到它们各自在 RAM 中的实际地址中。基于 RAM(即磁盘)的系统可以将初始值直接加载到最终 RAM 地址。
The CRT (C runtime) also zeroes out the bss which contains all the global and static variables that have no initializers. This was probably done as a precaution against uninitialized data. It is a relatively straightforward block fill operation because all the global and static variables have been crammed together into one address segment.
CRT(C 运行时)还将包含所有没有初始化程序的全局和静态变量的 bss 清零。这样做可能是为了防止未初始化的数据。这是一种相对简单的块填充操作,因为所有全局变量和静态变量都被塞进了一个地址段。
Of course floats and doubles mayrequire special handling because their 0.0 value may not be all zero bits if the floating format is not IEEE 754.
当然,浮点数和双精度数可能需要特殊处理,因为如果浮点格式不是 IEEE 754,它们的 0.0 值可能不是全零位。
Note that since autovariables don't exist at program load time they can'tbe initialized by the runtime startup code.
请注意,由于自动变量在程序加载时不存在,因此它们无法由运行时启动代码初始化。
回答by Jeffrey L Whitledge
Suppose you were writing a C compiler. You expect that some static variables are going to have initial values, so those values must appear somewhere in the executable file that your compiler is going to create. Now when the output program is run, the entire executable file is loaded into memory. Part of the initialization of the program is to create the static variables, so all those initial values must be copied to their final static variable destinations.
假设您正在编写一个 C 编译器。您希望某些静态变量具有初始值,因此这些值必须出现在编译器将要创建的可执行文件中的某个位置。现在当输出程序运行时,整个可执行文件被加载到内存中。程序初始化的一部分是创建静态变量,因此所有这些初始值必须复制到它们最终的静态变量目的地。
Or do they? Once the program starts, the initial values of the variables are not needed anymore. Can't the variables themselves be located within the executable code itself? Then there is no need to copy the values over. The static variables could live within a block that was in the original executable file, and no initialization at all has to be done for them.
还是他们?一旦程序启动,就不再需要变量的初始值。变量本身不能位于可执行代码本身中吗?这样就不需要复制这些值了。静态变量可以存在于原始可执行文件中的块中,并且根本不需要为它们进行初始化。
If that is the case, then why would you want to make a special case for uninitialized static variables? Why not just put a bunch of zeros in the executable file to represent the uninitialized static variables? That would trade some space for a little time and a lot less complexity.
如果是这样,那么您为什么要为未初始化的静态变量创建一个特殊情况?为什么不在可执行文件中放一堆零来表示未初始化的静态变量?这将用一些空间换取一点时间并降低复杂性。
I don't know if any C compiler actually behaves in this way, but I suspect the option of doing things this way might have driven the design of the language.
我不知道是否有任何 C 编译器实际上以这种方式运行,但我怀疑以这种方式做事的选择可能推动了语言的设计。
回答by James Curran
Mostly because the static variables are grouped together in one block by the linker, so it's real easy to just memset() the whole block to 0 on startup. I to not believe that is required by the C or C++ Standards.
主要是因为链接器将静态变量组合在一个块中,因此在启动时将整个块 memset() 设置为 0 真的很容易。我不相信 C 或 C++ 标准要求这样做。
回答by John
There is discussion about this here:
有关于这个讨论在这里:
First of all in ISO C (ANSI C), all static and global variables must be initialized before the program starts. If the programmer didn't do this explicitly, then the compiler must set them to zero. If the compiler doesn't do this, it doesn't follow ISO C. Exactly how the variables are initialized is however unspecified by the standard.
首先,在 ISO C (ANSI C) 中,所有静态和全局变量都必须在程序启动之前进行初始化。如果程序员没有明确地这样做,那么编译器必须将它们设置为零。如果编译器不这样做,则它不遵循 ISO C。然而,标准未指定变量的确切初始化方式。

