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

Yu *_*Hao 24 c

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

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

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

int* p = NULL;
Run Code Online (Sandbox Code Playgroud)

只是:做出任何改变:

int *p;
Run Code Online (Sandbox Code Playgroud)

Jer*_*fin 19

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

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

  • @YuHao:首先,我很确定标准实际上没有指定WHERE变量.只要它们出现在目标系统的内存中,那就没问题.对于它所关心的所有内存被称为"数据","bss"或"hhhaaa".但是,它确实定义了全局变量和静态变量应该以某种方式初始化,因此实现必须"做任何需要的事情" - 这可能只是将其留在BSS中并让操作系统将其设置为零,或者它可能需要一些代码来填充某些地方,而不是零. (2认同)

AnT*_*AnT 8

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

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

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

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

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

SomeType SomeClass::*p = 0;
Run Code Online (Sandbox Code Playgroud)

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