繁体   English   中英

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

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

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

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

按当前标准的15.5.3 我试图理解最新句子( This includes stack unwindings )是指什么:

  • 假设编译器必须负责展开堆栈吗?
  • 或者,它是说依赖于编译器是否放松堆栈?

问题来自以下片段:

#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(); (没有捕获异常),你有一堆堆栈没有被解开

所以,这两个实验似乎赞成上面的第一个子弹; clang ++和g ++都同意结果(但它不是判别式)。

此外,在我看来,非常奇怪的是标准,在指定对象的实时时间持续 时间时非常小心,这里留下了阴影。

愿有人澄清吗? 堆栈是否为标准保证的未捕获异常展开? 如果是的话,在哪里? 如果没有,为什么?

堆栈是否为标准保证的未捕获异常展开?

保证堆栈展开仅针对捕获的异常([except.handle] / 9):

如果找不到匹配的处理程序,则调用函数std::terminate() ; 在对std::terminate()调用是否为实现定义之前,是否展开堆栈。

所以它是实现定义的,否则。

如果没有,为什么?

如果发生未捕获的异常,标准会导致调用std::terminate 这表示程序执行的结束。 如果您有一些特定于平台的方法来记录当时系统状态的信息,您可能不希望该状态受到堆栈展开的干扰。

如果你没有这样做......那你就不在乎。

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

暂无
暂无

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

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