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