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