欢迎来到天天文库
浏览记录
ID:14342079
大小:63.50 KB
页数:7页
时间:2018-07-28
《vc++全局变量初始化-16.09.26》由会员上传分享,免费在线阅读,更多相关内容在行业资料-天天文库。
1、VC++全局变量Hanford2016年09月26日目录目录第1章说明21.1程序启动21.2强符号、弱符号21.3动态初始化顺序31.4exe调用dll41.5禁用动态初始化41.6应用实例5I第1章说明第1章说明1.1程序启动参考下面的C++代码:intGetC(){return2;};inta;intb=1;intc=GetC();intmain(){returna+b+c;}程序载入内存,全局变量a、b、c就完成了静态初始化(staticinitialization),此时a、b、c的数值分别
2、为0、1、0。系统会调用入口函数mainCRTStartup,后者会调用_initterm(__xc_a,__xc_z);执行_initterm函数时会调用GetC函数,完成全局变量c的动态初始化(dynamicinitialization)。此时a、b、c的数值分别为0、1、2。mainCRTStartup会接着调用函数main,至此完成程序的启动工作。注意:C语言里的全局变量只能静态初始化;C++语言里的全局变量才支持动态初始化。1.2强符号、弱符号上面示例代码中的全局变量a没有赋给初始值,它就是
3、弱符号。弱符号全局变量会被编译器初始化为零。上面示例代码中的全局变量b、c赋予了初始值,它们就是强符号。弱符号可能会被合并。如:1.cpp、2.cpp里均有弱符号a,那么连接时它们将被当做一个全局变量。又如:1.cpp、2.cpp里均有弱符号a,3.cpp里有强符号a,那么连接时以强符号为准。6第1章说明强符号是不会被合并的。如:1.cpp、2.cpp里均有强符号a,那么连接时就会出错。建议:尽量使用强符号,否则可能会产生难以察觉的错误。1.3动态初始化顺序C++代码里,可使用#pragmainit_
4、seg来调整动态初始化的顺序。其顺序一共分为52级,如下表所示:#pragmainit_seg(".CRT$XIA")#pragmainit_seg(".CRT$XIB").........#pragmainit_seg(".CRT$XIZ")#pragmainit_seg(".CRT$XCA")#pragmainit_seg(".CRT$XCB")#pragmainit_seg(".CRT$XCC")或#pragmainit_seg(compiler).........#pragmainit_seg
5、(".CRT$XCL")或#pragmainit_seg(lib).........#pragmainit_seg(".CRT$XCU")或#pragmainit_seg(user).........#pragmainit_seg(".CRT$XCZ")上表中,越靠上的段内全局变量越先被动态初始化。如下面的两个cpp文件内容:#pragmainit_seg(".CRT$XCC")intC1=GetC1();intC2=GetC2();#pragmainit_seg(".CRT$XCL")intL1=G
6、etL1();intL2=GetL2();全局变量C1、C2在段.CRT$XCC里,L1、L2在段.CRT$XCL里,所以C1、C2肯定比L1、L2优先完成动态初始化。同一段内全局变量的初始化顺序完全无法预料。如:上面C1、C2的动态初始化顺序是无法预料的。全局变量默认在段.CRT$XCU内,C++库的全局变量在段.CRT$XCC内,MFC库的全局变量在段.CRT$XCL6第1章说明内。所以,编写一个MFC程序并且静态连接MFC库时,C++库的全局变量首先被动态初始化,然后MFC库的全局变量被动态初始
7、化,最后是MFC程序里的全局变量被动态初始化。这样的动态初始化顺序非常重要,因为MFC程序里的全局变量有可能会调用C++库或MFC库里的函数或变量。不调整好顺序就有可能出错。如下面的代码:#include#include#pragmainit_seg(".CRT$XCA")std::strings="123";voidmain(){puts(s.c_str());}如果上述代码静态连接C运行时库,那么在C++库内的全局变量被初始化前,全局变量s就被动态初始化了。结果就
8、是s动态初始化失败,其成员变量全部为零(静态初始化的结果)。1.4exe调用dll上一节的例子,如果动态连接C运行时库(msvcrt.dll),那么全局变量s就能正常动态初始化。其初始化步骤为:1、初始化dll内的全局变量2、调用dll内的DllMain(...,DLL_PROCESS_ATTACH,...)3、初始化exe内的全局变量4、调用exe内的main或WinMain5、从exe内的main或WinMain返回6、销毁exe内的全局变量7、调用
此文档下载收益归作者所有