引发异常时引发异常 [英] Throwing an exception while throwing an exception

查看:120
本文介绍了引发异常时引发异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

此代码:

#include <iostream>
#include <stdexcept>

using namespace std;

int throw_it() {
  throw range_error( "foo" );
}

int main() {
  try {
    throw throw_it();
  }
  catch ( exception const &e ) {
    cerr << e.what() << endl;
    return 0;
  }
}

打印 foo 在运行时是否可以这样做?更具体地说,在引发异常的过程中引发异常是否会导致定义的行为?并且是抛出最近抛出异常的行为(就像上面的测试代码一样)吗?

prints foo when run, but is it guaranteed to do so? More specifically, does throwing an exception while in the process of throwing an exception result in defined behavior? And is that behavior to throw the most-recently-thrown exception (as the test code above does)?

FYI:

$ g++ --version
i686-apple-darwin11-llvm-g++-4.2 (GCC) 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2336.11.00)


推荐答案

只能评估一个异常一次。从15.1 / 7

Only one exception can be evaluated at a time. From 15.1/7


如果异常处理机制在完成对要抛出的表达式的求值之后但在捕获异常之前,调用a通过异常退出的函数std :: terminate被调用。

If the exception handling mechanism, after completing evaluation of the expression to be thrown but before the exception is caught, calls a function that exits via an exception, std::terminate is called.

在您的示例中, std :: terminate ()不会被调用,因为实际上仅引发了一个异常。当达到 throw_it(); 时,首先评估 throw_it(),结果该函数称为之前实际上会引发异常。由于该函数将引发异常,并且永远不会返回原始的 throw 。如果 throw_it()没有引发异常并返回整数值,则将执行调用throw表达式。因此,对于您的示例,保证可以打印 foo

In your example std::terminate() is not called because only one exception is actually being thrown. When throw throw_it(); is reached, throw_it() is evaluated first which results in the function being called before the exception is actually thrown. Since the function throws an exception and never returns the original throw is never reached. If throw_it() did not throw an exception and returned an integer value the calling throw expression would then be executed. So for your example foo is guaranteed to be printed.

但是从活动对象中抛出新异常该怎么办?处理程序?当发现异常时,将对其进行全面评估。当您抛出一个新异常(而不是使用 throw;重新抛出)时,原始异常将被销毁并开始评估新异常。

But what about throwing a new exception from within an active handler? When an exception is caught it has been fully evaluated. When you throw a new exception (rather than rethrowing with "throw;") the original exception is destroyed and evaluation of the new exception begins.

从15.1 / 4起


在最后一个剩余的活动处理程序退出异常之后,异常对象将被破坏,而不是通过重新抛出或...来实现。

The exception object is destroyed after either the last remaining active handler for the exception exits by any means other than rethrowing or....

这满足了一次只能评估一个异常的规则。

This satisfies the rule that only one exception can be evaluated at a time.

这篇关于引发异常时引发异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆