全局静态变量的动态初始化、竞争问题与时机
全局静态变量初始化的常见问题解答
问题1:全局静态变量的初始化时机是否有保证?会不会延迟?
全局静态变量的初始化分两种情况:
- 静态初始化:用常量表达式直接赋值的变量(比如
const static int num = 20;),必须在main()调用前完成初始化,绝对不会延迟。 - 动态初始化:需要运行时计算才能完成的初始化(比如
static int val = calc_init_val();),C++标准允许编译器做延迟初始化——不用非得在main()之前完成,只要在该变量第一次被使用前初始化好就行。不过动态库中的全局静态变量是例外:它们的初始化必须在LoadLibrary()/dlopen()返回前完成,不能延迟,否则动态库加载后无法正常使用。
问题2:跨翻译单元的全局静态变量初始化是否串行?会不会有竞争?
- 跨翻译单元的全局静态变量,初始化顺序没有固定规则(除非用
std::init_priority显式指定优先级),但所有全局静态变量的初始化过程都是在主线程中串行执行的——同一时间只有一个变量在初始化,所以初始化本身不会出现竞争问题。 - 但要警惕一种情况:如果某个全局变量的初始化函数里启动了新线程,这个新线程去访问另一个还没完成初始化的全局变量,就会出现竞争错误,这属于代码逻辑问题,不是标准初始化机制的问题。
- 补充:函数内部的静态变量(俗称“魔术静态”)是线程安全的,第一次访问时会原子性完成初始化,但全局/命名空间级别的静态变量没有这个线程安全特性。
内容的提问来源于stack exchange,提问作者albert
相关产品推荐
相关产品推荐

