c++中如何使用std::uncaught_exceptions_c++检查异常状态【详解】

10次阅读

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

c++中如何使用std::uncaught_exceptions_c++检查异常状态【详解】

这个函数名不存在——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 unwindingn";         } else {             // 可安全抛出(比如资源释放失败)             throw std::runtime_error("cleanup failed");         }     } };

注意:不能靠 std::uncaught_exception()(已弃用且行为不可靠),它只返回真假,无法区分嵌套异常。

立即学习C++免费学习笔记(深入)”;

容易踩的坑

  • std::uncaught_exceptions() 的值在 catch 块**入口处**就已减 1,所以你在 catch 里调用它会看到比抛出处少 1 的结果
  • 它对 noexcept 函数内的异常无特殊处理——只要异常对象已构造完成并抛出,计数就增加
  • 多线程下只反映**当前线程**的状态,不跨线程共享
  • 不要把它当作“是否有异常正在传播”的唯一依据:它不告诉你异常类型、位置或是否会被捕获,仅计数

真正关键的点在于:它解决的是“我是不是在栈展开中途”这个时序问题,而不是“有没有异常发生过”。用错时机或误读语义,反而会让错误更隐蔽。

text=ZqhQzanResources