简体   繁体   English

堆栈是否有c ++标准保证的异常展开?

[英]Is stack unwinding with exceptions guaranteed by c++ standard?

Concerning the stack unwinding, the c++ standard says: 关于堆栈展开,c ++标准说:

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]). 在完成异常对象([except.throw])的初始化之后,异常被认为是未捕获的,直到完成异常处理程序的激活([except.handle])。 This includes stack unwinding. 这包括堆栈展开。

at par 15.5.3 of the current standard. 按当前标准的15.5.3 I was trying to understand what the latest sentence ( This includes stack unwindings ) is referring to: 我试图理解最新句子( This includes stack unwindings )是指什么:

  • is it supposed that the compiler must take care of unwinding the stack? 假设编译器必须负责展开堆栈吗?
  • or, is it saying that it is compiler-dependent whether to unwind or not the stack? 或者,它是说依赖于编译器是否放松堆栈?

The question arises from the following snippet: 问题来自以下片段:

#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();
}

Now: 现在:

  1. if you run it as-is (catching the exception), you have a hint of the stack unwinding 如果按原样运行(捕获异常),则会显示堆栈展开的提示
  2. if you comment f(); 如果你评论f(); and uncomment g(); 并取消注释g(); (not catching the exception), you have hint of stack not being unwound (没有捕获异常),你有一堆堆栈没有被解开

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). clang ++和g ++都同意结果(但它不是判别式)。

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? 堆栈是否为标准保证的未捕获异常展开?

Stack unwinding is guaranteed to happen only for caught exceptions ([except.handle]/9): 保证堆栈展开仅针对捕获的异常([except.handle] / 9):

If no matching handler is found, the function std::terminate() is called; 如果找不到匹配的处理程序,则调用函数std::terminate() ; whether or not the stack is unwound before this call to std::terminate() is implementation-defined. 在对std::terminate()调用是否为实现定义之前,是否展开堆栈。

So it's implementation-defined, otherwise. 所以它是实现定义的,否则。

If not, why? 如果没有,为什么?

In the event of an uncaught exception, the standard causes std::terminate to be called. 如果发生未捕获的异常,标准会导致调用std::terminate 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. 如果你没有这样做......那你就不在乎。

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. 如果你真的需要总是解开堆栈,那么你可以把你的main代码(和任何线程函数)放在try {} catch(...) {throw;}块中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM