关于堆栈展开,c++ 标准说:
An exception is considered uncaught after completing the initialization of the exception object ([except.throw]) until completing the activation of a handler for the exception ([except.handle]). This includes stack unwinding.
在 par 15.5.3的现行标准。我试图理解最新的句子(这包括堆栈展开
)指的是:
- 是否假定编译器必须负责展开堆栈?
- 或者,是否展开堆栈取决于编译器?
问题来自以下片段:
#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 时非常小心的标准在这里留下了阴影。
谁能解释一下?标准是否保证未捕获异常的堆栈展开?如果是,在哪里?如果不是,为什么?
最佳答案
Is stack unwinding for uncaught exceptions guaranteed by the standard?
保证堆栈展开只发生在捕获异常([except.handle]/9):
If no matching handler is found, the function
std::terminate()
is called; whether or not the stack is unwound before this call tostd::terminate()
is implementation-defined.
所以它是实现定义的,否则。
If not, why?
如果发生未捕获的异常,标准会调用 std::terminate
。这代表程序执行的结束。如果您有某种特定于平台的方式来记录有关当时系统状态的信息,您可能不希望该状态受到堆栈展开的干扰。
如果你不这样做......那么你不管用哪种方式。
如果您确实需要始终展开堆栈,那么您可以将您的 main
代码(以及任何线程函数)放在 try {} catch(...) {throw ;}
block 。
关于c++ - c++ 标准是否保证堆栈展开并出现异常?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39962999/