The behavior in the operating systems where C was developed formed these Standard Conditions. When loading applications, the bootloader provides some memory for BSS . It is advisable to clear it to zeros, because if some other process used this memory before, the program that you run can track the contents of the previous memory of the process, potentially observing passwords, conversations or other data. Not every early or simple OS takes care of this, but most do it, so on most the initialization is actually โfreeโ, since this is the task that the OS will do anyway.
In this case, by default, 0 simplifies the implementation to see links to flags set during dynamic initialization, since there will be no uninitialized memory reading and subsequent undefined behavior. For example, given ...
void f() { static int n = g(); }
... the compiler / implementation can implicitly add something like the static bool __f_statics_initialised , which, fortunately, defaults to 0 / false due to nulling behavior - along with the initialization code, affinity (a thread-safe version is possible) ...
if (!__f_statics_initialised) { n = g(); __f_statics_initialised = true; }
In the above scenario, initialization is performed on the first call, but for global variables it is executed in the unspecified order for each object, sometimes before main() . In this case, the presence of some object-oriented initialization code and dynamic initialization, which is able to differentiate statics in an uninitialized state from those that they know should be set to non-zero values, makes it easy to write a reliable startup code. For example, functions can check whether the non-local static pointer 0 remains, and a new object for it, if so.
It should also be noted that many processors have highly efficient instructions for resetting large amounts of memory.
Tony delroy
source share