Я собираюсь использовать рабочий проект C ++ 20, так как формулировка там немного чище, хотя ни одно из настоящих правил не изменилось.
Во-первых, thread_local
ведет себя в основном как static
насколько нелокально идет: [basi c .st c .thread] / 2 :
[Примечание: переменная с продолжительностью хранения потока равна инициализируется, как указано в [basi c .start.static], [basi c .start.dynamic] и [stmt.dcl], и, если оно создано, уничтожается при выходе из потока ([basi c .start .срок]). - конец заметки]
Да, это заметка. Но нелокальный объект, объявленный thread_local
, в основном static
, так что это имеет смысл.
Теперь ни global
, ни thread
не имеют постоянной инициализации - поэтому оба инициализируются с нуля, а затем им требуется go dynamici c инициализация. До [basi c .start.dynamic] !
Dynami c инициализация нелокальной переменной с stati c длительность хранения неупорядочена, если переменная является неявно или явно созданной специализацией, частично упорядоченной, если переменная является встроенной переменной, которая не является неявно или явно созданной специализацией, а в противном случае упорядочена.
Ни одна из наших переменных не является специализацией, ни одна из них не является встроенной. Таким образом, оба упорядочены .
Объявление D является упорядоченным по внешнему виду перед объявлением E, если
- D появляется в та же единица перевода, что и E, или
- единица перевода, содержащая E, имеет интерфейсную зависимость от единицы перевода, содержащей D,
в любом случае до E.
Наши объявления не упорядочены по внешнему виду относительно друг друга.
Dynami c Инициализация нелокальных переменных V и W с stati c длительность хранения упорядочена как следует:
Хорошо, подпункт 1:
Если V и W имеют упорядоченную инициализацию, а определение V упорядочено по внешнему виду до определения W, или если V имеет частично упорядоченную инициализацию, W не имеет неупорядоченной инициализации, и для каждого определения E из W существует такое определение D из V, что D упорядочивается по внешнему виду до E,
Doesn ' т применить. Это сложное условие, но оно не применяется.
В противном случае, если программа запускает поток, отличный от основного потока, до инициализации V или W, не указывается, в каких потоках инициализируется V и W встречаются; инициализация не выполняется, если они происходят в одном и том же потоке.
Нет, нет потоков.
В противном случае инициализация V и W выполняется неопределенным образом.
Там мы go. global
и thread
имеют неопределенную последовательность.
Обратите также внимание на то, что:
Определяется реализацией, выполняется ли инициализация динамической c нелокальной встроенной переменной со значением stati c длительностью до первого оператора main или откладывается.
и:
Определяется реализацией, является ли динамическая c инициализация нелокальной не встроенной переменной с продолжительностью хранения потока секвенируется перед первым оператором начальной функции потока или откладывается.