威尔 C++不带参数的 throw 在另一个框架内工作以重新抛出异常?

发布于 2024-09-16 11:17:50 字数 370 浏览 6 评论 0原文

如果我有如下代码:

try {
  doSomething();
} catch (...) {
  noteError();
}

void noteError() {
  try {
    throw;
  } catch (std::exception &err) {
    std::cerr << "Note known error here: " << err.what();
  } catch (...) {
    std::cerr << "Note unknown error here.";
  }
  throw;
}

原始异常会从 noteError() 下框架内的两个地方抛出吗?

If I have a code like the following:

try {
  doSomething();
} catch (...) {
  noteError();
}

void noteError() {
  try {
    throw;
  } catch (std::exception &err) {
    std::cerr << "Note known error here: " << err.what();
  } catch (...) {
    std::cerr << "Note unknown error here.";
  }
  throw;
}

Will the original exceptions get thrown from both places inside the lower frame of noteError()?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

怂人 2024-09-23 11:17:50

你原来的代码没问题。您捕获了不同的异常类型并调用了一个函数来记录消息并重新抛出。 throw 语句不需要直接出现在相应的 catch 块内。如果您调用这些“note”函数之一并且您当前没有处理异常,那么您的程序将调用terminate()

你的新代码也很好。可以捕获所有内容,然后调用另一个重新抛出异常的函数以转到更具体的处理程序。这是异常调度程序中描述的习惯用法C++ 常见问题解答。在调度块完成之后重新抛出异常看起来有点奇怪,但是如果在 noteError 返回之后发生了相同的 throw 语句(在原来的catch块)而不是现在的位置,那么它将是完全普通的;标准 §15.1/6 中对此进行了演示。

Your original code was fine. You caught different exception types and called a function that would log a message and rethrow. The throw statement is not required to appear directly inside the corresponding catch block. If you call one of those "note" functions and you're not currently handling an exception, though, then your program will call terminate().

Your new code is also fine. It's OK to catch everything and then call another function that rethrows to go to a more specific handler. That's the exception dispatcher idiom described in the C++ FAQ. It looks a little peculiar to rethrow the exception after the dispatching block has finished, but if that same throw statement had occurred after noteError returned (inside the original catch block) instead of where it is now, then it would be perfectly ordinary; it's demonstrated in the standard, §15.1/6.

揽月 2024-09-23 11:17:50

标准(§15.1/2)中的措辞是(强调我的):

当抛出异常时,控制权将转移到最近的具有匹配类型的处理程序(15.3); “最近”表示 try 关键字后面的复合语句、构造函数初始化程序或函数体最近由控制线程输入且尚未退出的处理程序。

何时尝试阻止“退出”?根据语法 (§15/1),try 块以处理程序序列结束,因此块在最后一个处理程序结束时结束。换句话说:

try // <- start of try block
{
}
catch (whatever) // <- first handler
{
}
// ... more handlers
catch (whatever_again) // <- last handler
{
} // <- end of try block

所以是的,你的代码没问题。当重新抛出时,最近的 try 块有一个匹配的处理程序(即 catch (...)),因此进入该处理程序。

The wording in the standard (§15.1/2) is (emphasis mine):

When an exception is thrown, control is transferred to the nearest handler with a matching type (15.3); “nearest” means the handler for which the compound-statement, ctor-initializer, or function-body following the try keyword was most recently entered by the thread of control and not yet exited.

When has a try block "exited"? According to the grammar (§15/1), try blocks end with a sequence of handlers, so the block ends when the last handler ends. In other words:

try // <- start of try block
{
}
catch (whatever) // <- first handler
{
}
// ... more handlers
catch (whatever_again) // <- last handler
{
} // <- end of try block

So yes, your code is fine. When re-thrown, the nearest try block has a matching handler (namely catch (...)), so that handler is entered.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文