为什么全局variables和静态variables初始化为默认值?
在C / C ++中,为什么全局variables和静态variables初始化为默认值?
为什么不把它留在垃圾值? 这有什么特别的原因吗?
-
安全性 :单独留下内存会泄漏来自其他进程或内核的信息。
-
效率 :在初始化某些值之前,这些值是无用的,将它们置于具有展开循环的块中会更有效。 当系统空闲时,操作系统甚至可以将freelist页面置零,而不是当某个客户端或用户正在等待程序启动时。
-
可重复性 :只留下值将使程序行为不可重复,使得错误很难find。
-
优雅 :如果程序可以从0开始,而不必使用默认的初始化程序来混淆代码,那么它就更简洁。
有人可能会奇怪为什么auto
存储类的确是以垃圾的forms开始的。 答案是双重的:
-
从某种意义上说,它不是 。 每个级别的第一个堆栈框架页面(即每个添加到堆栈的新页面)确实接收到零值。 相同堆栈级别的后续函数实例所看到的“垃圾”或“未初始化”值实际上是您自己的程序及其库的其他方法实例留下的以前的值。
-
与初始化
auto
(函数本地)相关的任何事情都可能有一个二次的(或其他) 运行时性能损失 。 一个函数可能不会使用任何或所有大数组,例如,在任何给定的调用中,它可以被调用数千或数百万次。 静态和全局的初始化OTOH只需要发生一次。
因为在操作系统的适当配合下,可以实现零初始化静态和全局variables,而不会产生运行时开销。
6.7.8节C99标准的初始化(n1256)回答了这个问题:
如果具有自动存储持续时间的对象未被显式初始化,则其值是不确定的。 如果具有静态存储持续时间的对象未被明确初始化,则:
– 如果它有指针types,则它被初始化为空指针;
– 如果它有算术types,则它被初始化为(正或无符号)零;
– 如果它是一个聚合,每个成员根据这些规则初始化(recursion);
– 如果是联盟,则根据这些规则初始化(recursion)第一个命名成员。
考虑一下,在静态领域,你不能总是确定一些东西确实已经初始化了,或者主开始了。 还有一个静态的初始化和一个dynamic的初始化阶段,静态的初始阶段紧跟在顺序重要的dynamic阶段之后。
如果你没有把静力学归零,那么在这个阶段你就完全无法确定是否有什么东西被初始化了,简而言之,C ++世界将会飞散,像singletons(或者任何types的dynamic静态init)会简单地停止工作。
圆点的答案是热情的,但有点愚蠢。 这些都可以适用于非静态分配,但是这并没有完成(有时,但通常不)。
在C中,没有显式初始化的静态分配的对象被初始化为零(对于算术types)或空指针(对于指针types)。 C的实现典型地使用仅由零值位组成的位模式来表示零值和空指针值(虽然这不是C标准所要求的)。 因此,bss部分通常包括在文件范围(即在任何函数之外)声明的所有未初始化的variables以及用static关键字声明的未初始化的局部variables。
来源: 维基百科