fed*_*ino 19 c++ language-lawyer c++11
关于堆栈展开,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();
}
Run Code Online (Sandbox Code Playgroud)
现在:
f();和取消注释g();(没有捕获异常),你有一堆堆栈没有被解开所以,这两个实验似乎赞成上面的第一个子弹; clang ++和g ++都同意结果(但它不是判别式).
此外,在我看来,非常奇怪的是标准,在指定对象的实时时间和持续时间时非常小心,这里留下了阴影.
愿有人澄清吗?堆栈是否为标准保证的未捕获异常展开?如果是的话,在哪里?如果没有,为什么?
Nic*_*las 31
堆栈是否为标准保证的未捕获异常展开?
保证堆栈展开仅针对捕获的异常([except.handle]/9):
如果找不到匹配的处理程序,
std::terminate()则调用该函数; 在此调用之前是否展开堆栈std::terminate()是实现定义的.
所以它是实现定义的,否则.
如果没有,为什么?
如果发生未捕获的异常,则会std::terminate调用该标准.这表示程序执行的结束.如果您有一些特定于平台的方法来记录当时系统状态的信息,您可能不希望该状态受到堆栈展开的干扰.
如果你没有这样做......那你就不在乎.
如果您真的需要堆栈始终展开,那么您可以将main代码(和任何线程函数)放在一个try {} catch(...) {throw;}块中.