Я думаю, что моя проблема лучше всего описана в коде:
#include <stdio.h>
struct Foo;
extern Foo globalFoo;
struct Foo {
Foo() {
printf("Foo::Foo()\n");
}
void add() {
printf("Foo::add()\n");
}
static int addToGlobal() {
printf("Foo::addToGlobal() START\n");
globalFoo.add();
printf("Foo::addToGlobal() END\n");
return 0;
}
};
Foo globalFoo;
int dummy = Foo::addToGlobal();
int main() {
printf("main()\n");
return 0;
}
Вышеприведенные отпечатки (с gcc 4.4.3):
Foo::Foo()
Foo::addToGlobal() START
Foo::add()
Foo::addToGlobal() END
main()
Это то, что я ожидаю, и кажется логичным.
Однако, когда я заменяю следующие строки:
Foo globalFoo;
int dummy = Foo::addToGlobal();
в это:
int dummy = Foo::addToGlobal();
Foo globalFoo;
программа выводит следующее:
Foo::addToGlobal() START
Foo::add()
Foo::addToGlobal() END
Foo::Foo()
main()
Кажется, что экземпляры методов Foo
вызываются с использованием экземпляра, который еще не создан! Что-то простое, как перемещение объявления переменной в глобальной области, влияет на поведение программы, и это заставляет меня поверить (1) порядок инициализации глобалов не определен и (2) порядок инициализации глобальных переменных игнорирует все зависимости. Это верно? Можно ли убедиться, что конструктор Foo
вызывается до инициализации dummy
?
Проблема, которую я пытаюсь решить, статически ставит репозиторий элементов (статический экземпляр Foo
). В моей текущей попытке я использую макрос, который (помимо всего прочего) создает глобальную переменную (в анонимном пространстве имен, чтобы избежать столкновения имен), инициализация которой инициирует статическую инициализацию. Возможно, я решу проблему с неправильным углом? Есть ли лучшая альтернатива? Спасибо.