25

C standard guarantees that global and static variables, if not initialized, are always 0.

Here's my question: the un-initialized global and static variables go to BSS segment in the program. So the so called 0 should be all-bit 0.

For integral variables, all-bit 0 will be evaluated as 0. The floating point variables, if following IEEE 754, is also 0.0. But for pointers, null pointers is not necessarily to be all-bit 0, so does initialization of a global pointer like this:

int* p = NULL;

make any difference to just:

int *p;
Dimitar
  • 4,402
  • 4
  • 31
  • 47
Yu Hao
  • 119,891
  • 44
  • 235
  • 294
  • 4
    Here is some good information: http://en.cppreference.com/w/cpp/language/zero_initialization – Vaughn Cato Jun 09 '13 at 18:19
  • 2
    This is not a comment about what value `p` would have. It is a coding style idea. When you use `int *p`, it fails to emphasize the need for initialization to NULL. It suggest that initial value is a _don't care_, even if it is initialized to `NULL` by `C`. `int* p = NULL;` implies the program _needs_ to have that initialization. That is the difference I see. – chux - Reinstate Monica Jun 09 '13 at 18:31

2 Answers2

20

The standard guarantees that a pointer with static storage duration and no other initializer will be initialized to be a null pointer, regardless of what bit pattern that may involve.

The same basic idea applies to floating point and integer types as well -- they're guaranteed to be initialized to 0 or 0.0 as well. The implementation can leave this to the fact that BSS sets all bits to 0 if and only if it "knows" that doing so will result in the correct values.

Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
  • So that un-initialized variables doesn't have to go to BSS, this explains my problem, thanks. – Yu Hao Jun 09 '13 at 18:25
  • 2
    @YuHao: First of all, I'm pretty sure that the standard doesn't actually specify WHERE variables go. As long as they appear somewhere in the memory of the target system, that's fine. What that piece of memory is called could be "data", "bss" or "hhhaaa" for all it cares. It does, however, define that global and static variables should be initialized in a certain way, so the implementation has to "do whatever that takes" - which may be just leaving it in BSS and let the OS set that to zero, or it may require some code to fill certain places with something OTHER than zero. – Mats Petersson Jun 09 '13 at 18:31
  • @Yu Hao: It doesn't really matter whether it "goes to BSS" or not. The compiler can always generate startup initialization code that will override any effects of "being in BSS". So, BSS is completely inconsequential here. – AnT stands with Russia Jun 09 '13 at 18:35
  • @MatsPetersson and AndreyT: I got your point now, the compiler will generate the correct program no matter how the target system are implemented. I think I know the computer system more, thanks to both sincerely. – Yu Hao Jun 09 '13 at 18:44
8

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.

AnT stands with Russia
  • 312,472
  • 42
  • 525
  • 765