`
jgsj
  • 浏览: 960469 次
文章分类
社区版块
存档分类
最新评论

C++全局和静态变量初始化顺序的研究

 
阅读更多
C++全局和静态变量初始化顺序的研究
我在编程的时候遇到了一个非常棘手的问题,就是静态变量初始化的问题。有的情况一个全局(静态)变量依赖另外一个全局(静态)的变量。比如在工厂模式中使用隐式注册注册一个创造器(Creator),但是它要依赖工厂的初始化,如果工厂都没有初始化,那么注册会失败。程序会抛出一个未知的异常。这些是在C++进入main函数之前就已经完成的。在进入main函数之前,crt0dat.c会为这些全局或静态的变量赋初值。问题是一般的情况它们的初始化顺序到底如何?当初我也是一头雾,但是在自己上网提问和多次调试后,我终于知道了其中的奥秘。


我使用的环境是VS2005,也就是说使用的是VC++8的编译器。在编译的时候我们不是看到输出栏上显示的是编译的源文件吗?编译器在编译源文件的时候会记录那些处于全局范围的全局变量、全局静态变量以及类静态变量。按照编译的顺序形成一个表,然后运行时在main()函数开始之前就初始化,所以有时候我们看到有些程序打开的时候半晌才弹出一个窗口,比如说360,它在初始化之前做了很多的安全检测。


这里就讲得更细了。比如我有一个Factory<CEntity, string> g_Factory全局对象以及BlockCreator g_BlockCreator对象,由于全局变量不能在头文件中定义(如果包含了多个源文件的话会报LNK2005错误),我们将头文件中的Factory加上extern关键字,让它的定义推迟到源文件中。接下来如何保证g_BlockCreator在g_Factory后初始化了。
这里假设将g_Factory的定义放入Factory.cpp中,g_BlockCreator的定义放在Block.cpp中,按照VS2005字母表的编译顺序,Block.cpp将被先编译,Factory.cpp在之后编译,这样g_BlockCreator将先于g_Factory初始化,这是不允许的。所以我们将Factory.cpp改为$Factory.cpp(或者ASCII顺序排在B之前的字母都行),然后关闭VS2005,再打开进行编译,就能达到效果。记住改了文件名后一定要关闭VS2005,否则它还是会按照B-F的编译顺序进行编译的,尽管F开头的源文件已经不存在。重新打开后它就会按照$-B的顺序进行编译了,这会儿就不用担心不能保证初始化的顺序了。
分享到:
评论

相关推荐

    C++全局变量初始化的一点总结

     根据 C++ 标准,全局变量的初始化要在 main 函数执行前完成,常识无疑,但是这个说法有点含糊,main 函数执行前到底具体是什么时候呢?是编译时还是运行时?答案是既有编译时,也可能会有运行时(seriously), 从...

    C++各变量的区别

    3、全局区(静态区)(static)—,全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。 - 程序结束后有系统释放。 4、...

    C++中静态成员函数与静态成员变量(static )

    C++中静态成员函数与静态成员变量(static ) 这篇介绍了静态成员函数与静态成员变量,是我的读书笔记,我希望它够简短但又比较全面,起到复习的作用。如果有一些C++知识记不清楚了,它可以帮你很快回忆起来。 复习...

    C++中类成员变量初始化总结

    1、普通的变量:  一般不考虑啥效率的情况下 可以在...  2、static 静态变量:  static变量属于类所有,而不属于类的对象,因此不管类被实例化了多少个对象,该变量都只有一个。在这种性质上理解,有点类似于全局

    c_c++中内存区域划分大总结

    3.全局区(静态区),全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。- 程序结束释放 4.另外还有一个专门放常量的地方...

    c++静态局部变量和静态函数示例

    在函数体内定义了一个变量,每当程序运行到该语句时都会给该局部变量...静态局部变量在程序执行到该对象的声明处时被首次初始化,即以后的函数调用不再进行初始化(这一点非常的重要);静态局部变量一般在声明处初始化

    全局变量与局部变量在内存中的区别详细解析

    3、全局区(静态区)(static)—,全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域(.data),未初始化的全局变量和未初始化的静态变量在相邻的另一块区域(.bss)。 – 程序结束后由系统...

    C / C++ 各种 面试题 笔试题

    3、全局区(静态区)(static)—,全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。 - 程序结束后有系统释放 4、文字...

    关于C++中构造函数初始化成员列表的总结

     初始化列表的初始化顺序是依据类成员变量定义的顺序来决定的。 3.关于static const是否应该在初始化成员列表中初始化?  static const为全局静态常量,全局的意思是该变量属于整个类而非某个类实例,所以不能再...

    C++中 静态局部变量实例详解

    C++中 静态局部变量实例详解 以前经常使用和了解static作用在全局变量前,以至于甚至把static当做全局变量的代名词,但是其实static还可以作用于局部变量前 静态局部变量的意义: 1.分配空间在全局数据栈上 2.作用...

    C++中的栈和堆的区别

    3、全局区(静态区)(static)―,全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。 - 程序结束后有系统释放 4、...

    c语言stack(栈)和heap(堆)的使用详解

    3、全局区(静态区)(static)—全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。程序结束后由系统释放。4、文字常量区...

    关于堆栈、静态、动态内存的理解

    全局区(静态区)(static)—,全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域, 未初始化的全局变量、未初始化的静态变量在相邻的另一块区域。 - 程序结束后有系统释放 文字常量区 —...

    程序的内存分配

    3、全局区(静态区)(static)―,全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。 - 程序结束后有系统释放 4、文字...

    堆内存和栈内存详解 ESP

    3、全局区(静态区)(static)—,全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。 - 程序结束后有系统释放 4、文字...

    C++静态成员变量和静态成员函数的使用方法总结

    一.静态成员变量: 类体中的数据成员的声明前加上static关键字,该数据成员就成为了该类的静态数据成员。和其他数据成员一样,静态...//声明,标准c++支持有序类型在类体中初始化,但vc6不支持。 }; xxx.cpp文件 co

    预备知识―程序的内存分配

    的全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在相邻的 另一块区域。 - 程序结束后有系统释放 4、文字常量区 ―常量字符串就是放在这里的。 程序结束后由系统释放 5、程序代码区―...

    PC_Lint C/C++ 软件代码 静态分析工具

    它进行程序的全局分析,能识别没有被适当检验的数组下标,报告未被初始化的变量,警告使用空指针,冗余的代码,等 等。软件除错是软件项目开发成本和延误的主要因素。PClint能够帮你在程序动态测试之前发现编码错误...

    c++面试试题大全

    全局变量储存在静态数据库,局部变量在堆栈 10. 什么是平衡二叉树? 左右子树都是平衡二叉树 且左右子树的深度差值的绝对值不大于1 11. 堆栈溢出一般是由什么原因导致的? 没有回收垃圾资源 华为: 1、局部变量...

    C/C++程序内存的各种变量存储区域和各个区域详解

    C语言在内存中一共分为如下几个区域,分别是:1....全局变量、静态局部变量保存在全局数据区,初始化的和未初始化的分别保存在一起;普通局部变量保存在堆栈中;全局变量和局部变量在内存里的区别?一个由c/C++

Global site tag (gtag.js) - Google Analytics