Подтвердить что ты не робот

Пространства имен влияют на порядок инициализации в С++?

Глобальные переменные инициализируются в порядке появления в модуле трансляции и относительном порядке инициализации переменных в разных модулях перевода в неуказанном (так называемый "статический фиаско порядка инициализации" ).

Влияют ли пространства имен на это? Например, если у меня есть этот код:

//first.cpp
int first;
int second;

будет ли она иметь какую-либо разницу в порядке инициализации по сравнению с этим кодом:

//second.cpp
namespace {
int first;
}
int second;

Существуют ли случаи, когда помещение глобального объекта в пространство имен влияет на порядок инициализации?

4b9b3361

Ответ 1

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

Пространства имен не влияют на это - не упомянуты в разделе.

Что влияет на порядок разных единиц перевода. Если вам нужно определить порядок между ними, используйте расширение, такое как атрибут GCC constructor.

Ответ 2

Ну, "Глобальные переменные инициализируются в порядке появления в модуле перевода". Это не оставляет места ни для чего другого, например для пространств имен, чтобы повлиять на порядок.

Собственно, "глобальные переменные инициализируются по порядку..." - это неточное цитирование стандарта, как формально неверное. Точная формулировка из стандарта С++ Standard, ISO/IEC 14882: 2003, 3.6.2, пункт 1:

Объекты со статической продолжительностью хранения, определенные в области пространства имен в том же переводе единица и динамически инициализируется, должны быть инициализированы в том порядке, в котором их определение появляется в блоке трансляции.

Итак, вместо "global" он говорит "со статическим хранилищем", то есть все нелокальные переменные, являются ли они глобальными, членами пространства имен или членами класса и объявлены ли они static или нет.

Также он добавляет "и динамически инициализируется". Переменные с тривиальными конструкторами и постоянным инициализатором всегда инициализируются сначала (просто загружая их значения из двоичного файла), и все не константные инициализаторы оцениваются, а нетривиальные конструкторы выполняются в этом порядке. Это важно, поэтому вы можете, например, надежно создать связанный список в этих конструкторах; если голова является простым указателем, она уже инициализирована, поэтому вы можете безопасно работать с ней.