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

C++11 promise对象失效后关联future既不返回值也不抛异常问题

问题根因

你看到的程序打印到sub process 2就直接终止,根本不是promise析构导致的标准行为,核心是代码里有悬空引用触发了未定义行为:

  • main函数里的内层花括号是个独立作用域,你在里面定义的plocal和flocal都是栈上局部变量,作用域结束时会按声明逆序析构:后定义的flocal先销毁,之后才是plocal销毁。
  • 你创建子线程时传的是ref(flocal),等于子线程拿到的是栈上flocal变量的引用。等作用域跑完,flocal已经被析构释放了,子线程这时候执行到future.get(),相当于通过悬空引用访问已经不存在的对象,这是C++里典型的未定义行为——这种场景下程序怎么表现都不违反标准,直接崩溃被操作系统杀掉是最常见的结果,根本走不到你写的异常捕获逻辑,后面的打印自然出不来。
C++11标准下的预期行为

你要是想测promise析构对关联future的影响,得先把悬空引用的bug修了:把flocal的定义挪到内层作用域外面,保证子线程调用get()的时候,future对象本身还活着:

int main() {
    thread t;
    future<int> flocal; // future生命周期覆盖子线程整个运行周期
    {
        promise<int> plocal;
        flocal = plocal.get_future();
        t = thread(getValue, ref(flocal));
    } // 这里只有plocal被析构,flocal仍然有效
    t.join();
    return 0;
}

修正代码后的运行结果才是C++11标准明确规定的行为:

  • 当promise对象析构时,如果它关联的共享状态既没设置过值,也没设置过异常,会自动向共享状态写入一个错误码为broken_promise的future_error异常。
  • 子线程调用future.get()时会立刻抛出这个异常,被你写的catch (future_error &e)分支捕获,打印异常码和错误描述,最后输出sub process 4正常退出,不会出现直接终止的情况。

注意:只要代码里存在访问已销毁对象这类未定义行为,所有运行结果都不在标准的保证范围内,不管是直接崩溃、输出乱码还是看起来"正常运行"都有可能,不能拿未定义行为场景下的运行结果反推C++标准对promise/future的行为约定。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 04:16:21