为什么静态变量自动初始化为零?

j r*_*riv 13 c

可能重复:
为什么全局变量和静态变量初始化为默认值?

这种情况发生的技术原因是什么?所有平台的标准都支持它吗?如果未显式初始化静态变量,某些实现是否可能返回未定义的变量?

Jer*_*fin 37

由标准(§6.7.8/ 10)必需的.

没有技术上的理由它必须是这样的,但是这种方式已经足够长,以至于标准委员会将其作为一项要求.

如果不考虑这个要求,那么在许多(大多数?)情况下,使用静态变量会更加困难.特别是,您经常要进行一次初始化,并且需要一个可靠的起始状态,以便您知道某个特定变量是否已初始化.例如:

int foo() { 
    static int *ptr;

    if (NULL == ptr)
       // initialize it
}
Run Code Online (Sandbox Code Playgroud)

如果ptr在启动时可能包含任意值,则必须将其显式初始化为NULL,以便能够识别您是否已完成一次性初始化.

  • @paxdiablo:毫无疑问 - 它在K&R1(附录A,§6.8)中明确说明:"未初始化的静态和外部变量保证从0开始;未初始化的自动和寄存器变量保证以垃圾." (4认同)

nmi*_*els 11

是的,这是因为它符合标准; 但实际上,这是因为它是免费的.静态变量看起来就像生成的对象代码的全局变量.它们在.bss中分配,并在加载时与所有常量和其他全局变量一起初始化.由于它们所在的内存部分只是直接从您的可执行文件中复制而来,因此它们在编译时被初始化为免费已知的值.选择的值为0.

  • 无论如何,进程启动时未初始化的页面将全为零,除非内核不再编写随机垃圾.在任何现代实现中,bss是对所有进程共享的"零页面"的COW(写时复制)引用.即使不是这样,内核仍然必须采取措施防止新进程看到随机物理内存(可能包含私有内部内核数据或来自其他用户的数据)的内容,因此他们也可以将其设置为清除它时有用的值如0 (6认同)