全局变量初始化顺序及注意事项

时间:2022-02-10 21:21:41
   对于不同编译单位的全局变量,其初始化的顺序没有任何的保证,因此对不同编译单位里的全局变量,在它们的初始化顺序之间建立依赖性都是不明智的。
       此外也没办法捕捉到全局变量初始化抛出的异常,一般来说要减少全局变量的使用,特别是限制那些要求复杂初始化的全局变量。所以,尽量不用全局变量;用静态变量,通过访问器进行访问。
 
例如:全局变量  
        int   a   =   5;  
        int   b   =   a;  
       如果a和b定义在同一个文件里,那没什么问题,结果b等于5;如果a和b定义在不同文件里,就不能保证b也等于5,也就是说不能保证a先初始化。
       事实上,除了在同一个文件定义的全局对象的初始化是按照定义次序来进行的之外,其他全局或静态变量之间的初始化次序没有任何保障。解决这种问题的方法是不直接使用全局变量,而改用一个包装函数来访问,例如  
  int   get_a()  
  {  
          static   int   a   =   5;  
          return   a;  
  }  
  int   get_b()  
  {  
          static   int   b   =   get_a();  
          return   b;  
  }   
    
       这样的话,无论get_a和get_b是否定义在同一个文件中,get_b总是能够返回正确的结果,原因在于,函数内部的静态变量是在第一次访问的时候来初始化。 
       任何时候,如果在不同的被编译单元中定义了"非局部静态对象",并且这些对象的正确行为依赖于它们被初始化的某一特定顺序,就会产生问题.你绝对无法控制不同被编译单元中非局部静态对象的初始化顺序。对于函数中的静态对象(即"局部"静态对象)它们在函数调用过程中初次碰到对象的定义时被初始化..  
       PS:千万不要写出和编译顺序相关的程序来。 
 
       关于全局变量的初始化,C语言和C++是有区别的。      
       在C语言中,只能用常数对全局变量进行初始化,否则编译器会报错。       
       在C++中,如果在一个文件中定义了int a = 5;要在另一个文件中定义int b = a;的话,前面必须对a进行声明:extern   int   a;否则编译不通过。即使是这样,int b = a;这句话也是分两步进行的:在编译阶段,编译器把b当作是未初始化数据而将它初始化为0;在执行阶段,在main被执行前有一个全局对象的构造过程,int b = a;被当作是int型对象b的拷贝初始化构造来执行。    
      其实,准确地说,在C++中全局对象、变量的初始化是独立的,如果不是象int a   =   5;这样的已初始化数据,那么就是象b这样的未初始化数据。    
      而C++中全局对象、变量的构造函数调用顺序是跟声明有一定关系的,即在同一个文件中先声明的先调用。对于不同文件中的全局对象、变量,它们的构造函数调用顺序是未定义的,取决于具体的编译器。