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

C++中返回语句的拷贝构造函数异常是否会被函数内try-catch捕获?

C++返回值拷贝构造异常的捕获规则解析

可以保证异常被f内的catch捕获,而非抛至调用点,这是C++17及后续标准明确规定的行为。

标准依据

根据C++17标准(N4659)的[stmt.return]章节:

当return语句返回一个表达式时,该表达式的求值以及将其结果初始化到返回值对象的操作,都属于该return语句所在函数的执行上下文。如果这个初始化过程(包括可能的拷贝/移动构造)抛出异常,那么异常会在当前函数的范围内抛出,而非传递到调用者。

关于两个疑惑的解释

  • 与函数参数拷贝异常的区别:函数参数的拷贝构造是在调用者的执行上下文中完成的——调用者负责将实参拷贝到形参,所以这个过程抛出的异常会在调用点处理;而返回值的初始化(包括拷贝/移动)是在被调用函数的执行上下文中完成的,属于return语句执行逻辑的一部分,因此异常由被调用函数的异常处理机制处理。
  • return语句的控制权转移:return语句的执行分为两步:首先完成返回值的初始化(包括拷贝/移动操作),只有当这一步成功完成后,才会执行函数的退出逻辑(销毁局部变量、转移控制权到调用点)。如果初始化过程抛出异常,return语句的执行被中断,函数并未退出,控制权仍在f内部,因此异常会被f内的catch块捕获。

测试代码

#include<iostream>
    
struct S{
    S(const S &){
       throw "Oops";
    }
    
    S(int) noexcept  {}
};

S f(){
   
   static/*to avoid RVO*/ S stat(7);
   
   try{
      return stat;
   }catch(const char *what){
      std::cerr << "still in function after failed-return" << std::endl;
   }
   
   return S(7);// mandatory copy-elision (c++17); 
}

int main()
try{
   auto s = f();// mandatory copy-elision (c++17); 
 
}catch(...)
{
   std::cerr << "Exception from main..." << std::endl;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 10:52:05