Переменные со статической продолжительностью хранения инициализируются как следствие запуска программы. Переменные с продолжительностью хранения потока инициализируются как следствие выполнения потока. В рамках каждой из этих фаз инициализации инициализация происходит следующим образом.
A constant initializer для переменной или временного объекта o - это инициализатор, полное выражение которого является константным выражением, за исключением того, что если o это объект, такой инициализатор может также вызывать конструкторы constexpr для o и его подобъектов, даже если эти объекты относятся к нелитеральным типам классов. [ Note: Такой класс может иметь нетривиальный деструктор. ] выполняется, если переменный или временный объект со статической продолжительностью хранения или хранением потока инициализируется константным инициализатором для сущности. Если постоянная инициализация не выполняется, переменная с или есть . Вместе вызываются инициализация нулем и инициализация константой ; все остальные инициализации есть . Всякая статическая инициализация строго происходит до ( ) любой динамической инициализации. [ Динамическая инициализация нелокальных переменных описана в ; локальные статические переменные описаны в . ] — end note Constant initialization static storage duration thread storage duration zero-initializedstatic initialization dynamic initialization[intro.races] Note: [basic.start.dynamic] [stmt.dcl] — end note
Реализации разрешается выполнять инициализацию переменной со статической продолжительностью хранения или хранения потока в качестве статической инициализации, даже если такая инициализация не требуется статически, при условии, что
динамическая версия инициализации не изменяет значение любого другого объекта статического времени или продолжительности хранения потока до его инициализации, и
статическая версия инициализации производит то же значение в инициализированной переменной, которое было бы произведено динамической инициализацией, если бы все переменные, не требующие статической инициализации, были инициализированы динамически.
[ Note: Как следствие, если инициализация объекта obj1 относится к объекту obj2 области пространства имен, потенциально требующему динамической инициализации и определенному позже в той же единице преобразования, не указано, будет ли значение obj2 used значением полностью инициализированного obj2 (поскольку obj2 было статически инициализирован) или будет obj2 просто нулевым значением. Например,
inline double fd() { return 1.0; } extern double d1; double d2 = d1; // unspecified: // may be statically initialized to 0.0 or // dynamically initialized to 0.0 if d1 is // dynamically initialized, or 1.0 otherwise double d1 = fd(); // may be initialized statically or dynamically to 1.0
— end note ]