Выбор ответа Senior Сборка и линковка обновлено
Порядок инициализации глобальных объектов
Вопрос
Глобальный объект Logger log; в a.cpp в конструкторе обращается к глобальному Config cfg; из b.cpp. Чем это опасно?
Попробуйте сами
Выберите вариант, и откроется разбор.
Показать ответ и разбор
Коротко
Правильный ответ: Порядок инициализации глобальных объектов из разных .cpp не определён. Это static initialization order fiasco: стандарт задаёт порядок только внутри одной единицы трансляции.
Варианты ответа
- Ничем: объекты инициализируются в порядке файлов в командной строке
- Порядок инициализации глобальных объектов из разных
.cppне определёнправильный ответ - Ошибка компиляции: глобальный объект нельзя использовать в конструкторе
cfgбудет создан дважды: по разу на каждую единицу трансляции
Разбор
Это static initialization order fiasco: стандарт задаёт порядок только внутри одной единицы трансляции. Результат зависит от порядка линковки и может меняться при сборке. Решения: функция с локальной статической переменной Config& cfg() { static Config c; return c; }, constinit или constexpr для константной инициализации, явная инициализация в main.
- На порядок файлов в команде полагаться нельзя.
- Компилятор такое не диагностирует.
- Объект создаётся один раз, проблема в порядке.
Ответьте сами, а не прочитайте
В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.