是否通过c ++标准保证了异常的堆栈展开? [英] Is stack unwinding with exceptions guaranteed by c++ standard?

查看:84
本文介绍了是否通过c ++标准保证了异常的堆栈展开?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

关于堆栈展开,c ++标准说:

Concerning the stack unwinding, the c++ standard says:

完成异常对象([except.throw])的初始化直到完成异常处理程序([except.handle])的激活后,才认为未捕获异常.这包括堆栈展开.

An exception is considered uncaught after completing the initialization of the exception object ([except.throw]) until completing the activation of a handler for the exception ([except.handle]). This includes stack unwinding.

根据当前标准的参数15.5.3 进行.我试图了解最新句子(This includes stack unwindings)指的是什么:

at par 15.5.3 of the current standard. I was trying to understand what the latest sentence (This includes stack unwindings) is referring to:

  • 是否应该认为编译器必须注意展开堆栈?
  • 或者,是说是否要展开堆栈取决于编译器?

问题来自以下代码段:

#include <iostream>
#include <exception>

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

void f() {
    try{throw(0);}
    catch(...){}
}

void g() {
    throw(10);
}

int main() {
    S s;
    f();
    //g();
}

现在:

  1. 如果按原样运行它(捕获异常),则提示堆栈正在展开
  2. 如果您注释f();而取消注释g();(未捕获到异常),则提示堆栈未展开
  1. if you run it as-is (catching the exception), you have a hint of the stack unwinding
  2. if you comment f(); and uncomment g(); (not catching the exception), you have hint of stack not being unwound

因此,这两个实验似乎都支持上面的第一个项目符号; clang ++和g ++都对结果达成共识(但这不是判别式).

So, the two experiments seem to be in favor of the first bullet above; both clang++ and g++ agree on the result (but it is not a discriminant).

另外,在我看来,非常奇怪的是,在指定对象生存时间持续时间时非常谨慎的标准在这里留下了阴影.

Also, it seems to me very strange that the standard, which is really careful in specifying the object live time and duration is leaving a shadow here.

有人可以澄清吗?标准是否保证未展开异常的堆栈展开处理?如果是,在哪里?如果没有,为什么?

May anyone clarify? Is stack unwinding for uncaught exceptions guaranteed by the standard? If yes, where? If not, why?

推荐答案

对于标准所保证的未捕获异常,堆栈是否展开?

Is stack unwinding for uncaught exceptions guaranteed by the standard?

保证堆栈退绕仅在 capped 异常([except.handle]/9)下发生:

Stack unwinding is guaranteed to happen only for caught exceptions ([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.

否则,它是实现定义的.

So it's implementation-defined, otherwise.

如果没有,为什么?

If not, why?

如果发生未捕获的异常,则该标准将导致调用std::terminate.那代表程序执行的结束.如果您当时有某种特定于平台的方式来记录有关系统状态的信息,则可能不希望该状态因堆栈展开而受到干扰.

In the event of an uncaught exception, the standard causes std::terminate to be called. That represents the end of the execution of the program. If you have some platform-specific way of logging information about the state of the system at that time, you may not want that state to be disturbed by stack unwinding.

如果您不这样做,那么您将不在乎.

And if you're not doing that... then you don't care either way.

如果确实需要始终解开堆栈,则可以将main代码(以及任何线程函数)放在try {} catch(...) {throw;}块中.

If you truly need the stack to always be unwound, then you can put your main code (and any thread functions) in a try {} catch(...) {throw;} block.

这篇关于是否通过c ++标准保证了异常的堆栈展开?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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