使用静态数据的构造函数在main()之前执行工作
Using constructor of static data to perform work before main()
我们的系统有一个基于插件的架构,每个模块有效地有一个'主'功能。我需要在调用模块的main()
之前运行一小段代码。我已经成功地将代码放入一个虚拟类的构造函数中,然后声明该类的一个静态变量,例如:
namespace {
class Dummy {
public:
Dummy() { /* do work here */ }
};
Dummy theDummy;
}
void main() {...}
这似乎工作得很好,但它是一个有效的解决方案,在编译器保证代码将运行?它是否有机会检测到theDummy
在系统中的其他任何地方都没有被引用,并将其编译/链接完全删除,或者它会意识到构造函数需要运行?由于
这似乎工作得很好,但它是一个有效的解决方案,在编译器保证代码将运行?它是否有机会检测到dummy在系统中的其他任何地方都没有被引用,并将其编译/链接完全删除,或者它会意识到构造函数需要运行?
参见n3797 S3.7.1/2:
如果具有静态存储时间的变量具有初始化或具有副作用的析构函数,则即使它看起来未使用,也不应消除它,
是的,初始化必须运行。不能直接省略。
看到S3.6.2/4:
具有静态存储时间的非局部变量的动态初始化是否在main的第一条语句之前完成,这是由实现定义的。如果初始化延迟到main语句第一个语句之后的某个时间点,则初始化应发生在与待初始化变量在同一翻译单元中定义的任何函数或变量第一次使用(3.2)之前。
是的,初始化必须在任何代码在同一翻译单元中运行之前完成。
在你的插件中使用一个名为main()的入口点并不是特别重要。
你可以走了。
根据评论,您确实需要确保您的Dummy
构造函数和main
函数在相同的翻译单元中才能正常工作。如果它们单独编译并仅链接在一起,则此保证将不适用。
不要调用函数main()
,除非它是程序入口点。如果是,那么可以保证静态对象构造函数将在main()
之前被调用。
一旦main
启动,它保证在使用同一翻译单元中的任何函数或变量之前运行。
因此,如果像这里一样,它和main
在同一个翻译单元中,那么它就保证在main
之前运行。如果它在另一个事务单元中,那么它是由实现定义的,它是否会在main
之前运行。在最坏的情况下,如果程序没有使用来自相同翻译单元的任何内容,它可能根本无法运行。
一般来说,只有当编译器能够确定语义相同时,才允许编译器优化某些内容。因此,如果您调用任何它无法看到的函数,例如,那么它必须假设该函数有副作用,并且不会优化代码。
注意,转换单元之间可能存在初始化顺序问题,因为tu之间静态对象的初始化顺序通常不能保证。但是,可以保证在输入模块的"main"之前调用构造函数(假设相同的TU)。详细信息请参见c++ 11标准第3.6.2节。
如果平台特定的机制适合您,请考虑使用函数属性,这是由g++和clang++支持的
- 从不同目录执行时"symbol lookup error:",否则从构建目录执行时按预期工作
- C++ 在条件未按预期工作时执行
- 工作线程在执行太快后永久休眠
- 无法使用 Visual Studio 启动 DirectX 11 可执行文件,生成工作正常
- 程序按执行方式工作,直到我向其添加析构函数为止
- 等待所有线程完成一项工作,然后执行另一项工作
- 该程序在执行时停止工作.我在代码块中制作了这个程序
- 为什么将可执行文件重命名为临时文件的此代码段不能按预期工作?
- CLION 调试器在执行一个步骤后停止工作
- 从本地工作,但在执行之间的随机端口上没有收到任何内容
- 为什么添加代码会破坏工作,即使它没有执行?
- 现代C++.从继续执行的工作线程返回数据结构
- 我的程序在执行期间停止工作
- C 可执行文件不从文件夹工作,而是在Mac上从控制台上工作
- Java在QT 5.7中为Android执行但不执行C (在先前的QT中工作)
- 为什么函数 sleep() 在 klee 执行 Objectfile 时不能工作?
- 创建不需要任何进一步安装即可在其他计算机上工作的可执行文件?
- C ++:在我的代码中执行 while 循环无法正常工作
- 可执行文件无法正常工作 [Linux]
- 当类成员函数执行时,程序停止工作