该标准特别指出,静态持续时间变量(命名空间范围和类静态成员)的动态初始化不必在执行 main 之前发生:
“命名空间范围的对象的动态初始化(8.5、9.4、12.1、12.6.1)是否在 main 的第一个语句之前完成,是由实现定义的。” IS 3.6.2(3)
动态初始化不是[总是?] 实现的吗?有什么更好/更简单的方法来保证对象在使用前初始化?
您的问题的答案位于您引用的句子之后的下一句(ISO/IEC 14882-2003 的 3.6.2 中)。
是否由实现定义
或者不是动态初始化
对象的(8.5、9.4、12.1、12.6.1)
命名空间范围是在之前完成的
main 的第一个语句。如果
初始化被推迟到一些
第一个之后的时间点
main 的声明,它会发生
在第一次使用任何功能之前
或相同定义的对象
翻译单元作为对象
已初始化。
显然是为了确保某些变量X
已初始化,您只需在函数中使用main
(直接或间接)与变量在同一翻译单元中定义的任何函数或变量X
(例如,如果您直接或间接使用X
在功能上main
那么您可以确定它已经初始化)。
EDIT:
如果除了保证您使用的变量已经初始化(它总是如此 - 正如上面引用的标准文本所保证的那样)之外,您还想知道为什么标准包含初始化可能会延迟的规定main
执行开始。
我的意思是如果问题也是:为什么不直接要求所有初始化都在之前执行main
starts?
嗯,这绝对不是关于动态链接库 - 在开始之前初始化所有对象没有问题main
。这也不是关于动态加载图书馆(LoadLibrary
/dlopen
) - 它们显然不在 C++ 标准的范围内(例如,它们不受单一定义规则的约束,通常它们甚至可能不是 C++)。
理论上,此规定允许延迟初始化以避免不必要的运行时开销 - 例如除非您实际使用特定翻译单元(C++ 源文件)中的某些函数或对象,否则您不必执行其运行时初始化。但任何实现实际上都不可能在运行时执行延迟初始化 - 多线程同步对于这种初始化来说是一个挑战,并且本身就是一种运行时开销。
BUT每个单独的实现实际上所做的只是链接那些实际使用的模块(翻译单元)。因此,即使您链接到某些包含某些动态初始化对象的静态库(可能会产生副作用 - 例如文件创建或用户交互),但不使用同一翻译单元中的任何内容 - 实现也没有义务运行该对象的初始化根本不。因此,此规定允许避免在最终可执行文件中包含任何未使用的翻译单元 - 即使它们正式是程序的一部分。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)