news 2026/2/21 3:35:14

静态初始化顺序灾难(Static Initialization Order Fiasco)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
静态初始化顺序灾难(Static Initialization Order Fiasco)

前言:童鞋们有没有遇到过程序已启动就莫名地崩溃了?很多时候SIOF(Static Initialization Order Fiasco)是罪魁祸首。今天来讲讲静态初始化顺序问题。

目录

一、先看个例子

二、初始化逻辑

2.1 静态初始化

2.2 动态初始化

三、如何避免

3.1 判断是否是全局初始化阶段导致的崩溃

3.2 推荐的解决措施


一、先看个例子

假如我们有一个全局单例,在logger.cpp文件中:

// logger.cpp class Logger { public: void log(const char* msg); }; Logger g_logger; // 全局对象

在另一个service.cpp文件中,使用了上面的g_logger全局对象:

// service.cpp extern Logger g_logger; class Service { public: Service() { g_logger.log("Service started"); } }; Service g_service;

童鞋们看出上面代码中的问题了吗?

在对g_service对象进行构造的时候,很容易导致崩溃!为什么呢?

如果g_looger对象先于g_service对象初始化,那么就是安全的。那如果g_logger对象初始化在后,那么可怕的崩溃就发生了!

这就是初始化顺序问题导致的灾难。对于上述两个对象初始化谁先谁后,其实是无法保证的,因为它们在两个不同的源文件中,编译器的链接顺序是不确定的。【注:在同一源文件中的全局对象,初始化是按照其定义顺序进行的】

二、初始化逻辑

C++把全局、静态变量(非局部)的初始化分为两种:

2.1 静态初始化

零初始化:内存清0

常量初始化:编译器就能够确定的常量表达式,如:

int num = 2; const double pi = 3.14159;

这类初始化是程序启动前就完成了,几乎不会产生什么问题。

2.2 动态初始化

运行时的初始化,如:

调用构造函数:如,第一节中列举的例子

函数返回值初始化:如

int num = caculate();

这类初始化在程序一启动时候执行(在主程序之前,如main())。如果不注意初始化顺序,很容易出现程序崩溃问题。

三、如何避免

3.1 判断是否是全局初始化阶段导致的崩溃

全局初始化阶段崩溃,一般调用栈会出现以下关键字眼:

_init_term、__static_initialization_and_destruction_* global constructors keyed to dynamic initializer for

3.2 推荐的解决措施

使用函数内的静态局部变量,其特点是:

  • 首次进入时才进行构造;
  • 初始化顺序由调用流决定;
  • 线程安全(C++11及之后)。

根据这个思想,将第一节中的代码 进行优化:

// logger.cpp class Logger { public: void log(const char* msg); }; Logger& getLogger() { static Logger m_log; //静态局部,首次调用时构造,线程安全(C++11) return m_log; }
// service.cpp class Service { Service() { getLogger().log("Service started"); // 此时保证 Logger 已初始化 } }; Service g_service; // 仍然可以是全局,但它内部访问的是函数内 static

这就简单、完美地解决了初始化顺序导致的崩溃灾难!

感兴趣的童鞋可关注作者公众号(定期同步)

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/2/12 22:47:21

【热力学】一个反向热传递问题,并确定了对流换热系数,表面温度被用作边界条件来解决问题附matlab代码

✅作者简介:热爱科研的Matlab仿真开发者,擅长毕业设计辅导、数学建模、数据处理、建模仿真、程序设计、完整代码获取、论文复现及科研仿真。🍎 往期回顾关注个人主页:Matlab科研工作室👇 关注我领取海量matlab电子书和…

作者头像 李华
网站建设 2026/2/18 8:25:37

揭秘网络安全:从零基础到高手的必由之路

一、网络安全的定义 网络安全,是指通过采取必要措施,防范对网络的攻击、侵入、干扰、破坏和非法使用以及意外事故,使网络处于稳定可靠运行的状态,以及保障网络数据的完整性、保密性、可用性的能力 。其涵盖信息保密性、完整性、可…

作者头像 李华
网站建设 2026/2/19 16:12:22

2026最强Java面试八股文及答案整理

Java 面试 Java 面试随着时间的改变而改变。在过去的日子里,当你知道 String 和 StringBuilder 的区别就能让你直接进入第二轮面试,但是现在问题变得越来越高级,面试官问的问题也更深入。 在我初入职场的时候,类似于 Vector 与 A…

作者头像 李华
网站建设 2026/2/20 21:45:38

大模型从入门到精通:产业链、应用场景与市场前景全解析

本文全景分析人工智能大模型,详述其定义、分类、发展历程及产业链结构。大模型产业链包括基础层(算力、数据、算法)、模型层(通用和行业大模型)、应用层(To B和To C)及支撑服务,形成完整闭环。市场前景广阔,预计2028年全球AI支出将达6320亿美…

作者头像 李华
网站建设 2026/2/19 0:57:06

【面板数据】地市工业三废数据集(2003-2023年)

数据简介:工业三废是工业生产过程中产生的三类主要废弃物,包括废水、废气和废渣。它们若未经有效处理直接排放,会对环境、生态和人体健康造成严重危害。认识工业三废的危害,在于通过科学治理实现“环境-经济-社会”的多赢。它要求…

作者头像 李华