[英]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();
}
现在:
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.