静态初始化的相依性
今天又遇到了这个问题,就地总结下以免遗忘。
在一个编译单元(如一个.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 }
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首先被初始化,那么此时y为0,x = y + 1 = 1;
紧接着初始化y.cpp,y = 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语言中有如下限制:静态对象的初始化语句必须为常量表达式。