Do built-in type objects have a special static priority for the initialization order?

I would expect the following code to give a segmentation error (or otherwise UB):

struct T { T(); }; T t; char const* str = "Test string"; T::T() { std::cout << str; // zero-initialised, only! } int main() {} 

This is because t initialized to str . I expect str to keep the value (char const*)0 due to zero initialization. My interpretation of [C++11: 3.6.2/2] supports this.

However , the above snippet displays the string as expected (and I confirmed this behavior by also printing the pointer value).

Is there some static initialization rule that is missing here, which allows str initialize the value before t starts? Where is it in the standard?


This caused a static change of variables during the build , where the responder claimed that using char const* rather than std::string to statically avoid the static initialization fiasco. I did not agree, but now I am not sure ...

+6
source share
4 answers

I think I found it; what happens here is not so much about the built-in type as about the constant initializer:

[C++11: 3.6.2/2]: Variables with static storage duration (3.7.1) or thread storage duration (3.7.2) must be initialized with zeros (8.5) before any other initialization.

Continuous initialization is performed:

  • if each complete expression (including implicit conversions) that appears in the link initializer with a static or storage duration of streams is a constant expression (5.19), and the link is bound to the value l denoting an object with a static storage duration or a temporary one (see 12.2) ;
  • if the object with the statics or duration of the storage of flows is initialized with a constructor call, if the constructor is a constexpr constructor, if all constructor arguments are constant expressions (including conversions), and if after replacing the invocation function (7.1) .5), each constructor call and the full expression in mem -initializers and in initializers of brackets or equal for non-static data elements are a constant expression;
  • if the object with the statics or duration of the storage of threads is not initialized by calling the constructor, and if every complete expression that appears in its initializer is a constant expression.

Together, zero initialization and constant initialization are called static initialization; all other initialization is dynamic initialization. Static initialization must be performed before any dynamic initialization begins. [..]

This final sentence seems to override the subsequent rules of the sequence, making this ordering applicable to translation units.

+1
source

str initialized with a constant expression, and const char * is the POD type (C ++ 03, but C ++ 11 is similar, but with different terms and more allowed cases). Such initialization is performed in the static initialization phase, and the static initialization phase is of no order. This happens before any dynamic initialization. t initialized in the dynamic initialization phase.

+6
source

Built-in types are not initialized at all, in the usual sense. As a rule, their original content is displayed in memory directly from a special area of ​​the binary file as part of its download.

+1
source
 char const* str = "Test string"; 

is executed by the compiler / linker, so it exists in its “initialized state” before the program even starts to work.

0
source

Source: https://habr.com/ru/post/905252/


All Articles