是否在嵌套的"尝试"中重新抛出异常合法?

Ale*_*ler 22 c++ exception-handling

以下是否在C++中定义良好?我被迫"转换"异常返回代码(有问题的API被许多C用户使用,所以我需要确保在控制返回给调用者之前捕获并处理所有C++异常).

enum ErrorCode {…};
ErrorCode dispatcher() {
   try {
      throw;
   }
   catch (std::bad_alloc&) {
      return ErrorCode_OutOfMemory;
   }
   catch (std::logic_error&) {
      return ErrorCode_LogicError;
   }
   catch (myownstdexcderivedclass&) {
      return ErrorCode_42;
   }
   catch(...) {
      return ErrorCode_UnknownWeWillAllDie;
   }
}

ErrorCode apifunc() {
   try {
      // foo() might throw anything
      foo();
   }
   catch(...) {
      // dispatcher rethrows the exception and does fine-grained handling
      return dispatcher();
   }
   return ErrorCode_Fine;
}

ErrorCode apifunc2() {
   try {
      // bar() might throw anything
      bar();
   }
   catch(...) {
      return dispatcher();
   }
   return ErrorCode_Fine;
}
Run Code Online (Sandbox Code Playgroud)

我希望样本显示我的意图.我的猜测是这是未定义的行为,但我不确定.如果适用,请提供标准的报价.另外的方法也受到赞赏.

谢谢!

GMa*_*ckG 12

没关系.该异常处于活动状态,直到它被捕获,并且变为非活动状态.但它一直存在,直到处理程序的范围结束.从标准,强调我的:

§15.1/ 4:抛出的异常临时副本的内存以未指定的方式分配,除了3.7.4.1中所述.只要存在针对该异常执行的处理程序,临时就会持续存在.

那是:

catch(...)
{ // <--

    /* ... */

} // <--
Run Code Online (Sandbox Code Playgroud)

在这些箭头之间,您可以重新抛出异常.只有当处理程序范围结束时,异常才会停止存在.

请记住,如果您在dispatch没有活动异常的情况下进行呼叫,terminate则会被呼叫.如果dispatch在一个处理程序中抛出异常,则异常将开始传播.有关问题的更多信息.