关于堆栈展开,c ++标准说:
在完成异常对象([except.throw])的初始化之后,异常被认为是未捕获的,直到完成异常处理程序的激活([except.handle])。这包括堆栈展开。
目前标准的par 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();
}
现在:
f();
并取消注释g();
(未捕获异常),则表示您有未显示已展开的堆栈提示所以,这两个实验似乎赞成上面的第一个子弹; clang ++和g ++都同意结果(但它不是判别式)。
另外,我觉得非常奇怪的是,在指定对象实时时间和持续时间时非常小心的标准在这里留下了阴影。
愿任何人澄清吗?堆栈是否为标准保证的未捕获异常展开?如果是的话,在哪里?如果没有,为什么?
答案 0 :(得分:31)
标准保证的未捕获异常的堆栈展开吗?
只有捕获的异常([except.handle] / 9)才能保证堆栈展开:
如果找不到匹配的处理程序,则调用函数
std::terminate()
;在对std::terminate()
的调用是否为实现定义之前,堆栈是否已展开。
所以它是实现定义的,否则。
如果没有,为什么?
如果发生未捕获的异常,标准会导致std::terminate
被调用。这表示程序执行的结束。如果您有一些特定于平台的方法来记录当时系统状态的信息,您可能不希望堆栈展开会干扰该状态。
如果你不这样做......那你就不在乎。
如果您真的需要堆栈始终展开,那么您可以将main
代码(和任何线程函数)放在try {} catch(...) {throw;}
块中。