C 标准保证全局和静态变量,如果没有初始化,总是0
.
这是我的问题:未初始化的全局和静态变量进入BSS
程序中的段。所以所谓的0
应该是all-bit 0
。
对于积分变量,all-bit 0
将被评估为0
。浮点变量,如果遵循IEEE 754,也是0.0
. 但是对于指针,空指针不一定是all-bit 0
,所以像这样初始化全局指针:
int* p = NULL;
只是:
int *p;
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
value 来表示指向数据成员类型的空指针。例如
SomeType SomeClass::*p = 0;
实际上转化为填充p
全比特模式的代码。因此,如果您在没有显式初始化程序的情况下声明此类类型的静态变量,编译器将必须确保其初始值是全位模式,而不是全位零模式。众所周知,一些编译器会通过将这些变量放入 BSS 中而忘记它们而出错,从而使这些变量充满全位零模式。