静态对象析构未捕获异常:寻求C++标准对应规则
静态对象析构抛异常导致程序终止的标准规则分析
先看问题代码:
#include <thread> struct foo { ~foo() noexcept(false) { throw 0; } }; void func() try { static foo f; } catch(...) { } int main() { std::thread t{func}; t.join(); }
编译运行后会触发错误:terminating due to uncaught exception of type int。
你怀疑的[except.handle]/11条款并不适用,它的约束范围确实和当前场景不匹配——既不是main函数的function-try-block,也不是线程存储期对象的问题。
对应的正确标准规则
问题根源来自静态存储期对象的析构异常处理规则,对应C++标准的[basic.start.term]/6条款(不同版本编号可能略有差异,但核心逻辑一致):
如果静态存储期对象的析构函数抛出未被捕获的异常,程序会调用
std::terminate()终止运行。
具体原因解析
- 静态对象
f的构造发生在子线程第一次执行func()时,这个阶段如果抛异常,会被func的function-try-block捕获。但你的代码里构造没抛异常,问题出在析构阶段。 - 静态存储期对象的析构时机是程序终止阶段(也就是
main函数返回后),由主线程执行。此时func的function-try-block早已执行完毕并退出,没有任何catch块能覆盖这个阶段的异常。 - 当
foo的析构函数抛出int类型异常时,没有任何捕获逻辑,直接触发std::terminate(),也就是你看到的报错。
内容的提问来源于stack exchange,提问作者Mia
相关产品推荐
相关产品推荐

