之前看公司有人收集类元信息用的方法很巧妙,所以早就想写一篇关于动态初始化的博客,一则是想分享,二则是作为个人摘记.
在c++标准的initialization of non-local variable章节有如下描述
There are two broad classes of named non-local variables: those with static storage duration (3.7.1) and
those with thread storage duration (3.7.2). Non-local variables with static storage duration are initialized
as a consequence of program initiation. Non-local variables with thread storage duration are initialized as a
consequence of thread execution. Within each of these phases of initiation, initialization occurs as follows.
Together, zero-initialization and constant initialization are called static initialization ; all other initialization is
dynamic initialization . Static initialization shall be performed before any dynamic initialization takes place. Dynamic initialization
of a non-local variable with static storage duration is either ordered or unordered. Definitions of explicitly specialized class template
static data members have ordered initialization.
It is implementation-defined whether the dynamic initialization of a non-local variable with static storage
duration is done before the first statement of main. If the initialization is deferred to some point in time
after the first statement of main, it shall occur before the first odr-use (3.2) of any function or variable
defined in the same translation unit as the variable to be initialized.
非局部静态变量的初始化是否发生在主函数main之前则以依赖于编译器的实现,在msdn上能看到如下文档
C Run-Time Error R6030
CRT not initialized
This error occurs if you are using the CRT, but the CRT startup code was not executed.
It is possible to get this error if the linker switch /ENTRY is used to override the
default starting address, usually mainCRTStartup, wmainC RTStartup for a console
EXE,WinMainCRTStartup or wWinMainCRTStartup for a Windows EXE, or _DllMainCRTStartupfor a DLL.
Unless one of the above functions is called on startup, the C Runtime will not be initialized.
比如我们使用vc100编译器,默认的入口函数wmainCRTStartup,当然项目配置或者链接器提供/ENTRY参数进行入口函数的指定,对于DLL又有所不同,执行的_DLLMainCRTStartup函数,一般来说这些函数做了如下事情
including calling _CRT_INIT, which initializes the C/C++ run-time library and invokes C++ constructors on static, non-local variables
所以对于VC系列编译器CRT提供了动态初始化的实现,在CRT Initialization文档部分,我们看到如下描述