初始化全局变量和静态变量为0总是不必要的?

C标准保证全局变量和静态变量(如果未初始化)始终为0

这是我的问题:未初始化的全局变量和静态变量将转到程序中的BSS段。 所以所谓的0应该是all-bit 0

对于积分变量, all-bit 0将被评估为0 。 如果遵循IEEE 754 ,浮点变量也是0.0 。 但是对于指针,空指针不一定是all-bit 0 ,所以像这样的全局指针的初始化:

 int* p = NULL; 

对以下方面有所不同:

 int *p; 

该标准保证具有静态存储持续时间且没有其他初始化器的指针将被初始化为空指针,而不管可能涉及的位模式。

同样的基本思想也适用于浮点和整数类型 – 它们也保证初始化为0或0.0。 实现可以将此事实留给BSS将所有位设置为0的事实,当且仅当它“知道”这样做将导致正确的值。

保证具有静态存储持续时间的所有变量都被初始化为它们各自的零值,这通常并不意味着它们必须在物理上用全零位模式填充。

这些变量可能在某个特定平台上进入BSS段的原因是在目标平台上,空指针实际上由全位零模式表示。 即指针的全位零初始化恰好在该平台上正常工作,因此编译器使用BSS作为在该特定平台上实现正确行为的最简单且最有效的方式。 如果不是这种情况,则编译器必须以不同方式初始化此类静态变量。

这将适用于浮点值,例如,如果某些平台使用非IEEE 754表示来表示具有非零位模式的值来表示0.0 (C不要求IEEE 754)。

(此外,这甚至用于应用于大于char所有整数类型,直到其中一个用于C99标准的TC最终要求所有位零模式成为所有C平台上所有类型的整数零的有效对象表示。)

一个很好的现实生活中的例子来自C ++(一种不同的语言,但在这种情况下是相关的)。 C ++对具有静态存储持续时间的标量变量提供了相同的保证。 同时,许多流行的C ++实现使用0xFFFFFFFF值来表示指向数据成员类型的空指针。 例如

 SomeType SomeClass::*p = 0; 

实际上转换为用全位 – 一种模式填充p代码。 因此,如果在没有显式初始化程序的情况下声明此类型的静态变量,则编译器必须确保其初始值为全位 – 一个模式,而不是所有位零模式。 已知一些编译器通过将这些变量放入BSS而错误地将它们弄错,从而使这些变量充满了全零位模式。