news 2026/6/10 17:51:43

静态初始化顺序灾难(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/6/5 4:28:29

技术的终极善意:抹平集中式和分布式边界

在中国数据库市场,比“替代”更难的是选择。 如今,数据库已成为AI时代名副其实的数据底座,但国内企业技术决策者们却陷入一种前所未有的“选择焦虑”:数据库市场品牌林立,技术架构同质化严重,上百款数据库…

作者头像 李华
网站建设 2026/6/10 7:42:09

如何运用心理分析批评方法?

运用心理分析批评方法,核心是透过文本的表层叙事,挖掘其背后潜藏的无意识心理、人格结构、防御机制与深层情结,从而揭示文本、创作者与读者之间的心理关联。以下是具体的操作路径:一、 先做理论准备:锚定核心工具在展开…

作者头像 李华
网站建设 2026/6/5 13:00:50

[特殊字符] A1GIS 软件合集来了!一次集齐主流GIS工具

大家好!今天为大家整理了一份超全的 GIS软件合集,涵盖了ArcGIS各版本、ArcGIS Pro以及两款常用GIS软件,均为网络公开资源整理,方便大家学习研究使用! 🗺️ 一、ArcGIS 经典版本 适用于传统项目、教学及兼容…

作者头像 李华