C标准保证全局和静态变量(如果未初始化)始终为0
。
这是我的问题:未初始化的全局和静态变量转到程序中的BSS
段。因此,所谓的0
应为all-bit 0
。
对于积分变量,all-bit 0
将被评估为0
。如果遵循 IEEE 754 ,浮点变量也是0.0
。但是对于指针,空指针不一定是all-bit 0
,所以像这样初始化全局指针:
int* p = NULL;
与以下内容有所不同:
int *p;
答案 0 :(得分:19)
该标准保证具有静态存储持续时间且没有其他初始化程序的指针将被初始化为空指针,而不管可能涉及的位模式。
同样的基本思想也适用于浮点和整数类型 - 它们也保证初始化为0或0.0。实现可以将此事实留给BSS将所有位设置为0的事实,当且仅当它“知道”这样做将导致正确的值。
答案 1 :(得分:8)
保证所有具有静态存储持续时间的变量都被初始化为它们各自的零值,这通常并不意味着它们必须在物理上用全零位模式填充。
这些变量可能在某个特定平台上转到BSS段的原因是在目标平台上,空指针确实由全位零模式表示。即指针的全位零初始化恰好在该平台上正常工作,因此编译器使用BSS作为在该特定平台上实现正确行为的最简单且最有效的方法。如果不是这种情况,则编译器必须以不同方式初始化此类静态变量。
这适用于浮点值,例如,如果某些平台使用非IEEE 754表示来表示具有非零位模式的值来表示0.0
(C不强制要求IEEE 754)。
(此外,这甚至用于应用于大于char
的所有整数类型,直到C99标准的一个TC最终要求所有位零模式成为所有全零的有效对象表示。所有C平台上的类型。)
一个很好的现实生活中的例子来自C ++(一种不同的语言,但在这种情况下是相关的)。 C ++对具有静态存储持续时间的标量变量提供了相同的保证。同时,许多流行的C ++实现使用0xFFFFFFFF
值来表示指向数据成员类型的空指针。 E.g。
SomeType SomeClass::*p = 0;
实际上转换为使用all-bits-one模式填充p
的代码。因此,如果在没有显式初始化程序的情况下声明此类型的静态变量,则编译器必须确保其初始值为全位 - 一种模式,而不是全位 - 零模式。一些编译器通过将这些变量放入BSS中而错误地将它们弄错,从而使这些变量充满了全零位模式。