是否由c+保证异常情况下的堆栈展开+;标准 关于堆栈展开,C++标准表示:

是否由c+保证异常情况下的堆栈展开+;标准 关于堆栈展开,C++标准表示:,c++,c++11,language-lawyer,C++,C++11,Language Lawyer,在完成异常对象([except.throw])的初始化之后,直到完成异常处理程序([except.handle])的激活为止,异常被视为未捕获。这包括堆栈展开 在当前标准的基础上。我试图理解最新的句子(这包括堆栈展开))指的是什么: 是否认为编译器必须负责展开堆栈 或者,它是说是否展开堆栈取决于编译器 问题来自以下片段: #include <iostream> #include <exception> struct S{ S() { std::cout &l

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

在当前标准的基础上。我试图理解最新的句子(
这包括堆栈展开)
)指的是什么:

  • 是否认为编译器必须负责展开堆栈
  • 或者,它是说是否展开堆栈取决于编译器
问题来自以下片段:

#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();
}
#包括
#包括
结构{
S(){std::cout
标准是否保证未捕获异常的堆栈展开

只有捕获到的异常([except.handle]/9)才能保证堆栈展开:

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

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

若否,原因为何

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

如果你不这么做,那你就不在乎了


如果您确实需要堆栈始终展开,那么您可以将
main
代码(以及任何线程函数)放入
try{}catch(…){throw;}
块。

在发布的程序中,
s
在堆栈展开期间不会被销毁。它在
f()
返回后被销毁。“如果确实需要堆栈始终处于展开状态,那么可以将主代码放在try{}catch(…){throw;}块中。“-线程呢?我的直觉是,在这种情况下,单个线程入口函数也需要try-catch块,不是吗?@JohannGerell:我认为如果线程函数存在异常,那就是UB。@KerrekSB不,它是
终止
。我的程序通常以
int-main2();int-main(){try>之类的东西开始{return main2();}catch(…){global_handler();}}