当函数退出时有2个异常,原始异常会发生什么

时间:2013-06-09 23:44:36

标签: c++

注意:我在redhat linux 6.3上使用gcc 4.4.7。以下示例中的问题是关于GCC对从A::doSomething()抛出的第一个异常所做的事情,而不是关于是否应该从析构函数抛出异常。

在以下代码中,函数A::doSomething()以2 logic_error个例外退出。 析构函数logic_error中的第二个~A()似乎会覆盖logic_error中的A::doSomething()。 程序的输出如下:

我的问题是logic_error引发的A::doSomething()发生了什么。有没有办法恢复它?

#include <iostream>
#include <stdexcept>

#include <sstream>

using namespace std;

class A
{
public:
A(int i):x(i) {};
void doSomething();

~A() {
    cout << "Destroying " << x << endl;
    stringstream sstr;
    sstr << "logic error from destructor of " << x << " ";
    throw logic_error(sstr.str());
    }

private:
int x;
};

void A::doSomething()
{
A(2);
throw logic_error("from doSomething");
}


int main()
{

A a(1);
try
{
    a.doSomething();
}
catch(logic_error & e)
{
    cout << e.what() << endl;
}

return 0;
}

输出是:

Destroying 2
logic error from destructor of 2
Destroying 1
terminate called after throwing an instance of 'std::logic_error'
what():  logic error from destructor of 1
Aborted (core dumped)

1 个答案:

答案 0 :(得分:1)

编辑:在http://www.compileonline.com上进行实验我也发现观察到的行为很奇怪。看起来好像在不同的线程或异步上调用terminate(),而主线程在系统注意到它应该停止之前执行,甚至销毁A(1)。

重新读取C ++ 03它仍然表示相同,必须通过15.5.1p1b3终止调用,并且通过p2不允许任何其他内容。 gcc行为在这里显得不一致。

http://coliru.stacked-crooked.com/新的gcc输出上的

是:

Destroying 2
terminate called after throwing an instance of 'std::logic_error'
  what():  logic error from destructor of 2 

这是预期的一个(没有最后两行但我们可以在terminate()调用之后将其视为额外信息)。


符合实施的理论:

如果您编写类似的代码,请阅读GOTW#47SO thread

总结:语言规则是如果成功抛出异常(它被复制并且堆栈展开开始),并且在捕获它之前抛出另一个异常,则调用terminate()。由于不太可能以您想要的方式终止,请考虑重新安排代码以避免此问题。