You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++17中uncaught_exceptions()能否返回大于1的数值?

关于C++17中uncaught_exceptions()返回值大于1的场景疑问

C++17引入了int uncaught_exceptions() noexcept;来替代bool uncaught_exception() noexcept;,这引发了一个疑问:是否可能同时存在多个未捕获的异常?

根据相关文档描述:

返回值
2. 当前线程中未捕获异常对象的数量。

我尝试设想返回值大于1的场景,一开始想到的思路是:在同一个try块内,于局部变量的destructor中执行throw操作。但这并不可行:

  • 首先,这违反了析构函数必须为noexcept的规则;
  • 其次,即便通过noexcept(false)修正,程序也只会调用terminate,而非进入catch块。

另外,在catch块内抛出异常属于常规操作,但一旦进入catch块,uncaught_exceptions()的值就会递减至0,所以这种情况也无法让返回值大于1。

那么,是否存在能让uncaught_exceptions()返回大于1数值的场景?


答案是存在,典型场景是在异常栈展开(stack unwinding)的过程中,调用的某个函数(比如另一个对象的析构函数)再次抛出异常,且这个新抛出的异常被处理前的短暂阶段,uncaught_exceptions()的返回值会大于1。

举个具体的代码例子:

#include <iostream>
#include <exception>

struct Foo {
    ~Foo() noexcept(false) {
        throw std::runtime_error("Destructor exception");
    }
};

struct Bar {
    ~Bar() {
        std::cout << "uncaught_exceptions() during Bar destructor: " << std::uncaught_exceptions() << '\n';
        Foo f; // 析构Foo时抛出新异常
    }
};

int main() {
    try {
        Bar b;
        throw std::logic_error("Main exception");
    } catch (...) {
        std::cout << "uncaught_exceptions() in catch block: " << std::uncaught_exceptions() << '\n';
    }
}

这段代码的执行流程细节:

  1. main函数抛出logic_error,触发栈展开,开始销毁Bar对象;
  2. Bar的析构函数执行时,uncaught_exceptions()返回1(此时第一个异常还未被捕获);
  3. 创建Foo对象后销毁,Foo的析构函数抛出runtime_error,此时栈展开过程中存在两个未被处理的异常,uncaught_exceptions()的值变为2;
  4. 最终外层catch(...)捕获所有异常后,uncaught_exceptions()回到0。

需要注意的是,在C++11及以后,若在栈展开过程中(已有未捕获异常时)再次抛出异常且无对应处理,程序会调用std::terminate,但在抛出新异常到terminate被调用前的这个阶段,uncaught_exceptions()的返回值确实大于1。

内容的提问来源于stack exchange,提问作者unegare

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 07:22:23