Выбор ответа Senior Сборка и линковка обновлено

Порядок инициализации глобальных объектов

Вопрос

Глобальный объект Logger log; в a.cpp в конструкторе обращается к глобальному Config cfg; из b.cpp. Чем это опасно?

Попробуйте сами

Выберите вариант, и откроется разбор.

Показать ответ и разбор

Коротко

Правильный ответ: Порядок инициализации глобальных объектов из разных .cpp не определён. Это static initialization order fiasco: стандарт задаёт порядок только внутри одной единицы трансляции.

Варианты ответа

  1. Ничем: объекты инициализируются в порядке файлов в командной строке
  2. Порядок инициализации глобальных объектов из разных .cpp не определёнправильный ответ
  3. Ошибка компиляции: глобальный объект нельзя использовать в конструкторе
  4. cfg будет создан дважды: по разу на каждую единицу трансляции

Разбор

Это static initialization order fiasco: стандарт задаёт порядок только внутри одной единицы трансляции. Результат зависит от порядка линковки и может меняться при сборке. Решения: функция с локальной статической переменной Config& cfg() { static Config c; return c; }, constinit или constexpr для константной инициализации, явная инициализация в main.

  • На порядок файлов в команде полагаться нельзя.
  • Компилятор такое не диагностирует.
  • Объект создаётся один раз, проблема в порядке.

Ответьте сами, а не прочитайте

В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.