使用非std::exception派生类型调用std::promise::set_exception触发terminate的规范查询
关于std::promise传递非std::exception类型异常的行为
先看问题中的代码场景:
#include <iostream> #include <future> struct X {}; // 不继承std::exception的类型 int main() { auto ep = std::make_exception_ptr(X{}); // (1) std::promise<int> p; p.set_exception(ep); try { p.get_future().get(); // (2) } catch(const std::exception& exc) { std::cout << exc.what(); } return 0; }
当X不继承std::exception时,调用std::future::get()会触发std::terminate(),这一行为完全符合C++标准的规定:
std::future::get()的异常抛出规则
根据C标准(以C20为例,[futures.unique_future.get]条款),当std::promise通过set_exception设置了异常指针后,调用std::future::get()会重新抛出该异常指针指向的异常对象。未捕获异常的处理规则
标准中[except.terminate]条款明确:如果抛出的异常没有找到任何匹配的catch块,程序会调用std::terminate()终止执行。
在上述代码中,std::future::get()抛出的是X类型的异常,但catch块仅捕获const std::exception&类型的异常,没有匹配的处理逻辑,因此触发std::terminate()是必然结果。
需要注意的是,std::make_exception_ptr本身允许封装任意类型的异常对象,但这并不改变C++异常处理的核心规则——未被捕获的异常一定会导致程序终止。
内容的提问来源于stack exchange,提问作者user1832484
相关产品推荐
相关产品推荐

