Когда встроенные переменные в статическом хранилище инициализируются?

Стандарты C++ (по крайней мере, ранее C++17) говорили об этом в порядке инициализации.

Объекты со статической продолжительностью хранения, определенной в области пространства имен в одной и той же единице перевода и динамически инициализированной, должны быть инициализированы в том порядке, в котором их определение появляется в единице перевода.

C++17 вводит встроенные переменные, которые, как я полагаю, означают, что одна переменная со статической продолжительностью хранения и областью имен и динамической инициализацией может быть определена в нескольких единицах перевода.

Делает ли C++ какие-либо гарантии относительно порядка инициализации этих переменных?

1 ответ

Решение

Смотрите [basic.start.dynamic] p1:

Динамическая инициализация нелокальной переменной со статической длительностью хранения неупорядочена, если переменная является неявно или явно созданной специализацией, частично упорядочена, если переменная является встроенной переменной, которая не является неявно или явно созданной специализацией, и в противном случае упорядочена,

Поэтому тип переменной, которую вы описываете, имеет "частично упорядоченную инициализацию". Согласно п2:

Динамическая инициализация нелокальных переменных V а также W При статической длительности хранения упорядочиваются следующим образом:

  • ...
  • Если V имеет частично упорядоченную инициализацию, W не имеет неупорядоченной инициализации, и V определяется раньше W в каждой единице перевода, в которой W определяется, то
    • если программа запускает поток (4.7), отличный от основного потока (6.6.1), инициализация V сильно происходит до инициализации W;
    • в противном случае инициализация V последовательность перед инициализацией W,
  • ...

Итак, подведем итог, предполагая, что на рисунке нет созданных экземпляров шаблонов:

  • Если у вас есть две встроенные переменные пространства имен V а также W такой, что V определяется раньше W в каждой единице перевода, то V инициализируется раньше W,
  • Если только V встроенный, и W некоторая не встроенная переменная пространства имен, определенная ровно в одной единице перевода, V будет инициализирован раньше W так долго как Vопределение предшествует Wв этом едином переводческом блоке.
  • Если не встроенная переменная определена перед встроенной переменной, их порядок инициализации не может быть гарантирован. (По сути, вы можете себе представить, что реализация решает инициализировать единицы перевода в некотором порядке; она может выбрать одну из единиц перевода, содержащую только встроенную переменную, перед единицей перевода, которая содержит как встроенную переменную, так и не встроенную переменную.)

Также см. P5:

Это определяется реализацией, будет ли динамическая инициализация нелокальной встроенной переменной со статической продолжительностью хранения упорядочена перед первым оператором main или откладывается. Если оно откладывается, это сильно происходит перед любым использованием неинициализации odr этой переменной. Это определяется реализацией, в каких потоках и в каких точках программы происходит такая отложенная динамическая инициализация.

Другие вопросы по тегам