All variables with static storage duration are guaranteed to be initailized to their respective zero values, which generally does not mean that they have to be physically filled with all-bits-zero pattern.
The reason such variables might go to BSS segment on some specific platform is that on the target platform the null pointer is indeed represented by an all-bits-zero pattern. I.e. the all-bits-zero initialization for pointers just happens to work correctly on that platform, so the compiler uses BSS as the simplest and most efficient way to implement the correct behavior on that specific platform. If that was not the case, the compiler would have to initialize such static variables differently.
That would apply to floating-point values, for example, if some platform used non-IEEE 754 representation for such values with a non-zero bit pattern for representing 0.0
(C does not mandate IEEE 754).
(Moreover, this even used to apply to all integral types larger than char
, until one of the TCs for C99 standard finally required all-bits-zero pattern to be a valid object representation for integer zeros of all types on all C platforms.)
A good real-life example comes from C++ (a different language but relevant in this case). C++ makes the same guarantee for scalar variables with static storage duration. Meanwhile, many popular C++ implementations use 0xFFFFFFFF
value to represent null pointers of pointer-to-data-member type. E.g.
SomeType SomeClass::*p = 0;
actually translates into code that fills p
with all-bits-one pattern. So, if you declare a static variable of such type without an explicit initializer, the compiler will have to ensure that its initial value is all-bits-one pattern, not all-bits-zero pattern. Some compilers are known to get it wrong by putting such variables into BSS are forgetting about them, thus leaving such variables filled with all-bits-zero pattern.