我们的系统有一个基于插件的架构,每个模块都有效地拥有一个主要的'功能。我需要在调用模块main()
之前运行一小段代码。我已成功将代码放入虚拟类的构造函数中,然后声明该类的一个静态变量,例如:
namespace {
class Dummy {
public:
Dummy() { /* do work here */ }
};
Dummy theDummy;
}
void main() {...}
这似乎运行良好,但就编译器保证代码运行而言,它是否是一个有效的解决方案?是否有可能检测到theDummy
未在系统中的任何其他位置被引用并完全编译/链接它,或者它是否会意识到构造函数需要运行?感谢
答案 0 :(得分:1)
这似乎运行良好,但就编译器保证代码运行而言,它是否是一个有效的解决方案?是否有可能检测到该系统中的其他任何地方都没有引用该Dummy并完全编译/链接它,或者它是否会意识到构造函数需要运行?
见n3797 S3.7.1 / 2:
如果具有静态存储持续时间的变量具有初始化或具有副作用的析构函数,即使它看起来未使用也不应被删除,
是的,初始化必须运行。它不能简单地省略。
见S3.6.2 / 4:
实现定义了具有静态存储持续时间的非局部变量的动态初始化是否在main的第一个语句之前完成。如果初始化延迟到第一个main语句之后的某个时间点,它应该在与要初始化的变量相同的转换单元中定义的任何函数或变量的第一个odr-use(3.2)之前发生。
是的,必须在任何代码在同一个翻译单元中运行之前完成初始化。
在插件中使用名为main()的入口点并不是特别重要。
你很高兴。
根据评论,您需要确保Dummy
构造函数和main
函数位于同一个翻译单元中,以确保其正常工作。如果它们是单独编制的,只是链接在一起,则此保证不适用。
答案 1 :(得分:0)
通常,只有在可以确定语义相同的情况下,才允许编译器优化某些内容。因此,如果你调用任何它无法看到的函数,那么它必须假设该函数有副作用,并且不会优化代码。
请注意,您可能在翻译单元之间存在初始化顺序问题,因为通常无法保证TU之间静态对象的初始化顺序。但是,保证在输入模块的“main”之前调用构造函数(假设相同的TU)。有关详细信息,请参阅C++11 standard的第3.6.2节。
如果特定于平台的机制适合您,请查看使用g {+和clang ++支持的function attribute。
答案 2 :(得分:0)
除非是程序入口点,否则不要调用您的函数main()
。如果是,那么可以保证在main()
之前调用静态对象构造函数。
答案 3 :(得分:0)
main
启动后,保证在使用同一翻译单元中的任何函数或变量之前运行。
因此,如果它与main
位于同一翻译单元中,则保证在main
之前运行。如果它在另一个转换单元中,那么它的实现定义是否将在main
之前运行。在最坏的情况下,如果程序不使用同一翻译单元中的任何内容,则可能根本不运行。