Lot*_*har 17 c++ static-initialization
请考虑以下示例:
tt.h声明了一个带有外部链接的全局常量 extern int g_TRAGIC;
tt.cpp定义g_TRAGIC如下 const int g_TRAGIC = 0xF001;
my.cpp希望用它来定义自己的全局常量 const int g_MAGIC = g_TRAGIC;
当我读到iso-FAQ时,我会认为这会导致静态初始化顺序失败.然而,iso-FAQ注意到
在某些情况下,静态初始化顺序fiasco也可以应用于内置/内部类型.
这是什么某些情况下,是什么意思?对于内置/内在类型,我们在哪些条件下保存并从SIOF发出声音,特别是常量?或者必须将Construct On First Use Idiom用于所有具有外部链接的常量?
注意:在实际代码中,我无法更改g_TRAGIC的定义.
编译器可以生成不同类型的代码。
编译器将名称及其初始值发送到数据节中。
.data
dw myData 6
Run Code Online (Sandbox Code Playgroud)
它在编译时初始化,并在程序的整个生命周期中安全地定义
另一种选择是编译器为变量保留一些空间,并为数据创建一个初始值设定项/构造函数,然后在 之前调用构造函数main。执行析构函数(如果需要)atexit。
class CriticalSection {
CRITICAL_SECTION m_myCS;
public:
CriticalSection() {
InitializeCriticalSection( &m_myCS );
}
~CriticalSection() {
DeleteCriticalSection( & m_myCS );
}
} cs;
Run Code Online (Sandbox Code Playgroud)
一些数据可以在两个阶段中执行。
struct Data {
bool initialized;
void *(*pMalloc)( size_t size );
} FixMalloc = { true, MyMalloc };
Run Code Online (Sandbox Code Playgroud)
我见过编译器(VS2013)生成的代码initialized在静态数据中初始化为 true,但创建了一个在运行时分配的pMalloc函数MyMalloc。(这是因为 MyMalloc 没有已知常量。)
SomeClass * GetSomeClass()
{
static SomeClass cls;
return &cls;
}
Run Code Online (Sandbox Code Playgroud)
这是定义的顺序 - 当它被调用时,但需要一个完整的C++11编译器是线程安全的。
保证是:-
保证不是:-
在调用 main 之前,静态和 C/C++ 运行时都会引导。构造顺序问题也会发生在代码和运行时之间,因此您可能会使用复杂的构造函数来构造一些项目,这些项目依赖于不可用的服务。