std::uncaught_exceptions 是 C++17 引入的合法函数,用于返回当前线程中尚未被处理的异常数量,需包含 头文件,典型用途是在析构函数中判断是否处于栈展开过程以避免二次抛出。

这个函数名不存在——std::uncaught_exceptions_c++ 是完全错误的写法,C++ 标准库里没有这个标识符。
std::uncaught_exceptions 是 C++17 引入的合法函数
你真正想用的是 std::uncaught_exceptions(注意:是函数,不是带下划线后缀的变量或宏),它返回当前线程中“尚未被处理”的异常数量(即已抛出但还未进入任意 catch 块的异常个数)。
- 它不是布尔开关,而是整数计数器:嵌套抛出时可能返回 2、3 等
- 仅在异常处理流程中才有意义;正常执行时返回 0
- 必须包含
头文件 - C++17 起标准化,C++14 及更早版本不可用(某些编译器提供非标扩展,但不可移植)
典型使用场景:避免在析构函数中意外抛出异常
最常见用途是在析构函数里判断是否正处于栈展开(stack unwinding)过程中,从而避开二次抛出导致 std::terminate。
#include#include struct Guard { ~Guard() { if (std::uncaught_exceptions() > 0) { // 正在处理异常,不抛新异常,只记录或静默处理 std::cerr << "cleanup during stack unwinding\n"; } else { // 可安全抛出(比如资源释放失败) throw std::runtime_error("cleanup failed"); } } };
注意:不能靠 std::uncaught_exception()(已弃用且行为不可靠),它只返回真假,无法区分嵌套异常。
立即学习“C++免费学习笔记(深入)”;
容易踩的坑
-
std::uncaught_exceptions()的值在catch块**入口处**就已减 1,所以你在catch里调用它会看到比抛出处少 1 的结果 - 它对
noexcept函数内的异常无特殊处理——只要异常对象已构造完成并抛出,计数就增加 - 多线程下只反映**当前线程**的状态,不跨线程共享
- 不要把它当作“是否有异常正在传播”的唯一依据:它不告诉你异常类型、位置或是否会被捕获,仅计数
真正关键的点在于:它解决的是“我是不是在栈展开中途”这个时序问题,而不是“有没有异常发生过”。用错时机或误读语义,反而会让错误更隐蔽。











