Interfaces
I.22
Избегайте сложной инициализации глобальных объектов
Причина
Сложная инициализация может привести к неопределённому порядку выполнения.
Пример
// file1.c
extern const X x;
const Y y = f(x); // читаем x; пишем y
// file2.c
extern const Y y;
const X x = g(y); // читаем y; пишем x
Поскольку x и y находятся в разных единицах трансляции, порядок вызовов f() и g() не определён; один из них получит доступ к неинициализированному const. Это показывает, что проблема порядка инициализации для глобальных объектов (области пространства имён) не ограничивается глобальными переменными.
Примечание
Проблемы порядка инициализации становятся особенно сложными в параллельном коде. Как правило, лучше вообще избегать глобальных объектов (области пространства имён).
Контроль
- Помечать инициализаторы глобальных объектов, вызывающие не-
constexprфункции - Помечать инициализаторы глобальных объектов, обращающиеся к объектам типа
extern