C++全局对象析构函数调用std::exit的标准行为问询
问题结论
行为性质:未定义行为
你遇到的多平台表现不一致的根本原因是,该代码的行为属于C++标准规定的未定义行为,标准没有统一约束,编译器和运行时的任意处理都符合规范。
核心依据
C++标准中std::exit的基础行为继承自C标准,而C标准明确规定:多次调用exit函数的行为是未定义的。
你的代码刚好触发了多次exit调用:
main函数正常返回后,C++运行时会隐式调用std::exit启动程序终止流程- 静态存储期对象
foo进入析构阶段,析构函数中显式调用了第二次std::exit
完全符合多次调用exit的未定义场景。
不同平台表现差异的原因
两类表现都是未定义行为的合法实现:
- Linux GCC/Clang、原生Windows MSVC的C++运行时,会维护全局状态标记,记录当前是否已经进入
std::exit的终止流程。当检测到重入调用std::exit时,会直接调用底层操作系统的进程终止接口,不再重复执行静态对象销毁、atexit回调调用逻辑,因此程序可以正常以退出码0结束。 - MSYS2 GCC 10.3的C++运行时没有做这类重入检测,每次调用
std::exit都会完整执行你引用的[support.start.term]/9.1规定的流程:再次触发静态存储期对象销毁,foo的析构函数被反复调用,形成无限递归,最终栈溢出崩溃。
对标准条款的补充说明
你找到的[support.start.term]/9.1和[basic.start.term]/1两个条款,都只规范了**单次正常调用std::exit**的行为,没有覆盖重入调用的场景,因此不能作为该行为明确定义的依据。
内容的提问来源于stack exchange,提问作者yeputons
相关产品推荐
相关产品推荐

