【问题标题】:when function exits with 2 exceptions, what happens to the original exception [duplicate]当函数以 2 个异常退出时,原始异常会发生什么[重复]
【发布时间】:2013-06-05 14:25:36
【问题描述】:

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

在以下代码中,函数 A::doSomething() 退出时出现 2 个 logic_error 异常。 析构函数~A() 中的第二个logic_error 似乎覆盖了A::doSomething() 中的logic_error。 该程序的输出如下所示。

我的问题是A::doSomething() 抛出的logic_error 发生了什么。有办法恢复吗?

#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)

【问题讨论】:

  • 请修正缩进。目前无法阅读。

标签: c++


【解决方案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()。由于不太可能以您想要的方式终止,请考虑重新排列代码以避免此问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-03-20
    • 2016-12-12
    • 2010-12-12
    • 2011-03-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多