1998年C ++标准的一些相关摘录:
具有静态存储持续时间的对象的存储应在任何其他初始化发生之前进行零初始化。使用常量表达式进行零初始化和初始化统称为静态初始化;所有其他初始化是动态初始化。 具有使用常量表达式初始化的静态存储持续时间的POD类型的对象应在任何动态初始化发生之前进行初始化。在同一转换单元中的命名空间作用域中定义并动态初始化的静态存储持续时间的对象应在它们的定义出现在翻译单元中的顺序。
实现定义是否在
main
的第一个语句之前完成命名空间作用域对象的动态初始化。如果初始化延迟到某个时间点在main
的第一个语句之后,它应该在第一次使用与要初始化的对象相同的翻译单元中定义的任何函数或对象之前发生。
请考虑以下代码。
int a = 1;
int main()
{
cout << a << endl;
return 0;
}
根据标准,静态初始化在动态初始化之前进行,动态初始化可以在输入main()
之后进行。我的问题是:输入a
之前,全局变量1
是否已初始化为main()
?然后,如果在输入main()
之后创建了所有线程,则保证全局变量的静态初始化是线程安全的。
答案 0 :(得分:5)
标准表示在该翻译单元中调用任何函数之前,所有对象都在相同的翻译单元(也就是对应于单个源文件的目标文件)中初始化。在您的示例中,看起来它们位于同一文件中,因此a
将在调用main()
之前进行初始化。
该标准允许在运行时加载DLL的情况下进行延迟初始化。如果您允许代码的运行时链接,则不能说在main()
之前所有内容都已初始化。
答案 1 :(得分:0)
是的,如果你有一个像
之类的功能之外的对象Foobar foo;
如果Foobar有一个构造函数,它名义上会在main()之前运行。同样,它的析构函数在main()退出后运行。我会犹豫是否要使用这个功能。一个问题是,如果在多个文件中有这些对象,则创建顺序是不确定的。