提问人:Dmitry Kuzminov 提问时间:5/4/2023 最后编辑:Dmitry Kuzminov 更新时间:5/5/2023 访问量:170
如何避免延迟静态存储时长变量的初始化?
How to avoid deferring the initialization of static storage duration variables?
问:
我的构造函数中有副作用的类,这些类的对象是具有静态存储持续时间的全局对象。在初始化期间,这些对象在特殊映射中注册其类,在将此映射用于其他目的之前,必须进行这些注册。
类及其全局对象在单独的转换单元中定义,并且根据非块变量的动态初始化规则,初始化可以延迟到使用这些转换单元中的其他函数或变量,这可能意味着初始化被无限期延迟。
我正在寻找一种方法来避免这些全局对象的延迟初始化。说我的意思是对象的构造函数应该在它开始之前或之后被调用,但所有的更改都应该在这些对象的转换单元内完成。换言之,每当再添加一个具有全局对象的翻译单元时,不得修改其他翻译单元。main
更新:下面是一个示例:
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;
这个想法是自动调用的。但不能保证它会,因为此调用可能会被推迟:Object::Registrator::Registrator()
它是实现定义的,动态初始化是否 静态存储持续时间为 在 main 或的第一个语句之前排序,是延迟的。如果是 延迟,它强烈发生在任何非初始化 ODR 使用 任何非内联函数或在其中定义的非内联变量 翻译单元作为要初始化的变量。是的 实现定义了哪些线程以及 程序发生这种延迟的动态初始化。
答:
正如您在问题中所指出的,动态初始化是直接还是间接地通过 .main
在输入之前,也没有其他标准方法来执行代码。main
所以,我认为你不能得到一个独立于实现的保证。该标准还涵盖了一些用例,例如在运行时动态加载库,例如使用 .在这些情况下,在输入之前无法执行库中包含的代码。dlopen
main
您必须寻找实施保证或实施特定功能。比如Linux上的GCC/binutils,只要你不链接,,等,而你忽略,我认为不会有任何延迟初始化。--as-needed
--gc-sections
dlopen
评论
main
main
评论