Я недавно стал мучительно осведомлен о Static Initialization Order Fiasco. Мне интересно, однако, если правило, что «порядок инициализации не определено в единицах перевода» по-прежнему сохраняется для статических членов в родительском классе, которые необходимы статическим членам в дочернем классе.Статический порядок инициализации в иерархии классов
Например, говорят, что мы (за исключением, для краткости, все # стражников и включает в себя)
// a.h
class A {
static int count;
static int register_subclass();
};
// a.cpp
int A::count = 0;
int A::register_subclass() {
return count ++;
}
а затем подклассы A
,
// b.h
class B : public A {
static int id;
};
// b.cpp
int B::id = A::register_subclass();
Есть два перевода единицы здесь со статическими объектами в одном в зависимости от статических объектов в другом при инициализации ... похоже, что это может быть экземпляр фиаско порядка статического инициализации.
Мой вопрос: действительно ли он безопасен?
То есть, я уверен, что нет никаких шансов, что B::id
будет содержать мусор, скопированный с A::count
, до того, как последний будет инициализирован? Из моих собственных тестов A
всегда сначала инициализируется, но я не уверен, как вводить шум в порядке инициализации, чтобы увеличить вероятность сбоя, если поведение не определено.
Нет. Порядок подключения a.cpp и b.cpp к исполняемому файлу * не * гарантирован. Это * - «фиаско порядка инициализации». (Ваш линкер может использовать алфавитный порядок, или он может не быть). –
@BoPersson Я боялся этого. Благодарю. Сделать это ответ (и, может быть, предоставить ссылку?), И я пометю его принятым – stett
@BoPersson: Ответы идут туда приятель ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ –