【发布时间】:2017-02-19 03:41:43
【问题描述】:
关于堆栈展开,c++ 标准说:
在完成异常对象的初始化 ([except.throw]) 直到完成异常处理程序的激活 ([except.handle]) 后,才认为异常未被捕获。这包括堆栈展开。
在当前标准的par 15.5.3。我试图理解最新的句子 (This includes stack unwindings) 指的是什么:
- 是否假定编译器必须负责展开堆栈?
- 或者,是否展开堆栈取决于编译器?
问题出自以下sn-p:
#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++ 都同意结果(但这不是判别式)。
另外,在我看来很奇怪的是,在指定对象 live time 和 duration 时非常小心的标准在这里留下了阴影。
谁能解释一下?标准是否保证未捕获异常的堆栈展开?如果是,在哪里?如果不是,为什么?
【问题讨论】:
-
在发布的程序中,
s在堆栈展开期间不会被破坏。f()返回后销毁。
标签: c++ c++11 language-lawyer