全局静态变量的初始化
2026/1/8大约 2 分钟
一、 问题现状
最近发现一个Bug,关于两个全局静态变量间的初始化和相互依赖。可以简单描述为:
- 有两个全局变量a和b,类型分别为ClassA和ClassB
- 在ClassA类型的构造函数中,使用了全局变量b
- 在实际使用过程中,a和b的初始化时机不确定,导致a随机出现问题
#include <iostream>
class ClassA
{
public:
ClassA();
private:
int varA = 0;
int varA2 = 0;
};
class ClassB
{
public:
ClassB(int v);
int GetInt();
private:
int varB = 0;
};
static ClassA a;
static ClassB b(5);
static int c = 8;
ClassA::ClassA() { varA = b.GetInt(); varA2 = c; }
ClassB::ClassB(int v) { varB = v; }
int ClassB::GetInt() { return varB; }
int main()
{
std::cout << "Hello World!\n";
}上面代码也许一眼能看出来a在b之前进行了初始化,就算出问题也无非是a中获取到了错误的int值,那把问题复杂化一下:
- 如果全局静态变量a和b在不同头文件中定义呢?
- 如果有很多类似a的全局变量这样使用b呢?
- 如果b是一个指针、或b的成员中含有指针呢?
- 如果上述a依赖b的过程,被隐藏到main函数之前执行的某个很深的函数调用中呢?
此时就很难确定两个全局变量之间的初始化顺序了,并且会导致变量访问出错进而崩溃。
二、全局静态变量的初始化
初始化分为静态初始化、动态初始化:
- 静态初始化,用常量来对全局变量进行初始化的情况。根据变量是否设置初始值分别放于 data segment 段(设置初值)和 bss 段(未设置初始值)
- 动态初始化(运行期)(main 函数前,局部静态变量除外)
