Почему глобальные встроенные переменные и статические встроенные члены в C ++ 17 нуждаются в защите? - PullRequest
19 голосов
/ 28 июня 2019

Начиная с C ++ 17, можно инициализировать глобальные переменные и статические члены в заголовках, используя ключевое слово inline. Хотя я понимаю, почему статические переменные в функциях должны быть защищены (поскольку инициализация должна происходить только один раз, даже в многопоточном контексте), я не понимаю, почему эти новые встроенные переменные также защищены (вы можете увидеть это здесь: https://godbolt.org/z/YF8PeQ). Я думал, что в любом случае инициализация всех глобальных и статических элементов происходит в начале выполнения программы (даже до main()), поэтому в данный момент нет необходимости думать о нескольких потоках. Не могли бы вы объяснить это, пожалуйста?

1 Ответ

23 голосов
/ 28 июня 2019

Каждый файл, который содержит определение и использует его, будет пытаться инициализировать переменную. Даже если это происходит последовательно, а не одновременно, вам все равно нужен способ пометить переменную как инициализированную, так что только первое вхождение будет инициализировать ее, а последующие попытки инициализировать ее ничего не сделают.

Кроме того, вы можете создать несколько потоков до запуска main. Конструкторы глобальных переменных (и функции, вызываемые этими конструкторами) могут порождать новые потоки.

Таким образом, вы можете иметь несколько фрагментов кода, все они выполняются до main, все они пытаются инициализировать одну и ту же переменную. Вот для чего охранники.

...