静态初始化的相依性

今天又遇到了这个问题,就地总结下以免遗忘。

 

在一个编译单元(如一个.c.cpp文件)中,静态对象的初始化顺序与该对象出现在此编译单元中的顺序相同;而清除该对象的顺序则与初始化的顺序相反。

(注:函数内部的静态对象在函数第一次被调用时初始化,且只被初始化一次。)

但是如果多个静态对象被定义在不同的编译单元中,那么它们的初始化顺序将是不确定的。示例如下:

  1  // x.cpp

 2  extern int y;
 3  int x = y + 1;
 4   
 5  
 6  // y.cpp
 7  extern int x;
 8  int y = x + 1;
 9   
10 
11  // main.cpp
12  #include<iostream>
13  using namespace std;
14  
15  int main()
16  {
17      extern int x, y;
18      cout << "x=" << x << " y=" << y;
19  }

程序的静态初始化会保证静态对象被初始化为0,所以在执行程序员指定的初始化行为之前,x, y会被先初始化为0

如果x.cpp首先被初始化,那么此时y0x = y + 1 = 1

紧接着初始化y.cppy = x + 1 = 2

 

如果y.cpp首先被初始化,那么正好相反,x = 2, y = 1

 

实际运行的效果如下:

GCC4.6

程序运行结果为 x=2, y=1

而在VC++2010

程序运行结果为 x=1, y=2

 

有两种解决方式

1. 不使用全局的静态对象,避免出现初始化时相互依赖。这是最好的方法了。

2. 把发生依赖的静态对象定义放在一个文件中。

注:C语言中的限制

关于静态初始化,C语言中有如下限制:静态对象的初始化语句必须为常量表达式 

原文地址:https://www.cnblogs.com/hdtianfu/p/2580163.html