为什么仅对已处理的异常保证堆栈退卷? [英] Why is stack unwinding guaranteed only for handled exceptions?

查看:87
本文介绍了为什么仅对已处理的异常保证堆栈退卷?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

C ++ 标准说( [except.handle] / 9 ):

C++ standard says ([except.handle]/9):


如果找不到匹配的处理程序,函数std :: terminate()被调用;

If no matching handler is found, the function std::terminate() is called; whether or not the stack is unwound before this call to std::terminate() is implementation-defined

例如,代码的行为是实现定义的,在调用std :: terminate()之前是否取消堆栈的堆栈下面的代码(是否打印 S ::〜S())定义为实现:

For example, behavior of code below (will it print S::~S() or not) is implementation defined:

struct S {
    S() { std::cout << "S::S()" << std::endl; }
    ~S() { std::cout << "S::~S()" << std::endl; }
};

int main() {
    S s;
    throw std::runtime_error("exception");
}

我想深入了解 :为什么要定义实现?为什么在未捕获到异常的情况下调用 std :: terminate()之前无法解开上下文的原因(类似于 try { ...} catch(...){throw;} 在顶层函数中)?乍一看,与RAII一致,这种行为更加清晰和安全。

I would like to know in-depth: why is it implementation defined? Why a context cannot be unwinded up to its entry before std::terminate() is called if an exception is uncaught (which is similar to try{ ... } catch(...) { throw; } in the top-level function)? At a glance, such behavior is much clearer and safer in consistence with RAII.

推荐答案

如果未捕获到异常,则 std :: terminate 被调用。我们失败了,很糟糕,主机环境需要介入并且(也许)在我们之后进行清理。在这种情况下,释放堆栈就像给神风敢死队的飞行员戴头盔。

If an exception isn't caught, std::terminate is called. We failed so bad the host environment needs to step in and (maybe) clean up after us. Unwinding the stack in this case is like giving a helmet to a kamikaze pilot.

因此,在托管环境中,什么也不做,让主机托管可能更有意义。

So for a hosted environment, it may make more sense to just do nothing and let the host clean up.

现在,如果您处于独立的实现中,并且抛出异常,那么在您之后没有人需要清理。在这种情况下,实现应该预先释放堆栈,因为这是清理混乱的原因。

Now, if you are in a stand alone implementation, and are throwing exceptions, then there is no one to clean up after you. An implementation should preform stack unwinding in this case, because that's what is supposed to clean up the mess.

标准将其留给实现,以方便这两个截然不同的执行

The standard leaves it to the implementation to facilitate these two very different execution environments.

就像@Matteo指出的那样, std :: terminate ,因为您可以为其设置处理程序。只要堆栈尚未解开,该处理程序就可以对堆栈状态做一些有用的事情。

Like @Matteo pointed out, std::terminate is called before any potential unwinding because you can setup a handler for it. And that handler can do something useful with the stack state, so long as the stack isn't unwound yet.

这篇关于为什么仅对已处理的异常保证堆栈退卷?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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