I have classes with side effects in their constructors, and objects of these classes are global objects that have static storage duration. During the initialization these objects register their classes in a special map, and it is important for these registrations to happen before this map is used for other purposes.
The classes and their global objects are defined in separate translation units, and according to the dynamic initialization of non-block variables rules, the initialization can be deferred until other functions or variables from these translation units are used, and that may mean that the initialization is deferred indefinitely.
I'm looking for a way to avoid deferred initialization of these global objects. Saying that I mean that the constructors of the objects shall be called either before main
or right after its start, but all the changes shall be done inside translation units of these objects. In other words, whenever one more translation unit with global objects is added, no other translation unit shall be modified.
Update: here is an example:
struct Base {
};
extern void regFactoryMethod(std::function<std::shared_ptr<Base>()>);
struct Object : Base {
struct Registrator {
Registrator() {
regFactoryMethod([](){ return std::make_shared<Object>(); });
}
};
static Registrator registrator;
};
Object::Registrator Object::registrator;
The idea is that the Object::Registrator::Registrator()
is automatically called. But it is not guaranteed that it would, as this call may be deferred:
It is implementation-defined whether the dynamic initialization of a non-block non-inline variable with static storage duration is sequenced before the first statement of main or is deferred. If it is deferred, it strongly happens before any non-initialization odr-use of any non-inline function or non-inline variable defined in the same translation unit as the variable to be initialized. It is implementation-defined in which threads and at which points in the program such deferred dynamic initialization occurs.