Why should the static variables of the file region be initialized to zero?

C ++ default initialization does not nullify variables with automatic storage, why special handling for static storage variables?

Was it something specific C and C ++ just compatible? If in this case, why does C decide to do zero initialization?

If the static variables of the file region are equipped with an initializer, they are first initialized with zeros and then initialized with constant / dynamics again. Isn't that redundant? For example, the following code from cppreference: http://en.cppreference.com/w/cpp/language/zero_initialization

#include <string> double f[3]; // zero-initialized to three 0.0's int* p; // zero-initialized to null pointer value std::string s; // zero-initialized to indeterminate value // then default-initialized to "" int main(int argc, char* argv[]) { static int n = argc; // zero-initialized to 0 // then copy-initialized to argc delete p; // safe to delete a null pointer } 

In this case, why cannot n be initialized directly by argc?

EDIT: The question answered a part of this question: Static initialization of variables? But I do not think this is a duplicate, because the answers in another question did not answer my second question, i.e. why 2-step initialization. Also, the name of another post does not really say what the question is.

+7
c ++ c initialization
source share
3 answers

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.

+12
source share

Zero initialization of global tables comes "for free" because the storage for them is allocated in the "BSS" segment before the start of main (). That is, when you access the pointer p , the pointer itself must be stored somewhere, and this somewhere is actually a specific piece of bits in BSS. Since it must be initialized with something, why not zero?

Now, why don't auto / stack variables do this? Because it will be worth the time: allocation on the stack is nothing more than an increment (or decrease, point of view) of the stack pointer. Whatever garbage is, you can leave it there (according to C). Since we cannot get null-init for free, we wonโ€™t get it at all (because again itโ€™s C, where we donโ€™t like to pay for what we donโ€™t use).

Default initialization std :: string or other type of class a bit more complicated: C ++ requires that it be initialized in some way, and the default constructor, of course, the one that is used, and, yes, technically it is initialized to zero in the first place but as discussed, zero-init happened "for free." This may be acceptable for an implementation that may be sufficient to analyze the std :: string, to determine at build time how to initialize your bits, as if it were caused by a default constructor, but I do not know whether any implementation completed.

+7
source share

Global and static variables in C have a fixed memory address throughout the entire program life cycle. This allows the launcher to launch them by copying the corresponding memory area from the executable file to the computer's memory.

As a result, C can (should) provide an initial value for each static / global variable. If the user does not provide any value, the standard behavior should use zero. Unlike a local variable, this does not increase either memory or application speed (since the value must be written anyway).

Ultimately, this behavior (copying static source data to an executable file) can be very bad if you have large arrays without any source data. In fact, it seems that modern C compilers can avoid this waste and fill zero with large arrays instead of storing zeros in an exectuable program. However, once the rule has been provided, they are forced to fill in the region, even if the user may not need it. In any case, this is a very cheap operation, which is performed once when the program starts.

+3
source share

All Articles