gpt4 book ai didi

c++ - c++ 标准是否保证堆栈展开并出现异常?

转载 作者:IT老高 更新时间:2023-10-28 21:55:51 26 4
gpt4 key购买 nike

关于堆栈展开,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();
}

现在:

  1. 如果您按原样运行它(捕获异常),您会看到堆栈展开的提示
  2. 如果您注释 f(); 并取消注释 g();(未捕获异常),则提示堆栈未展开

所以,这两个实验似乎支持上面的第一个项目符号; clang++ 和 g++ 都同意结果(但它不是判别式)。

另外,在我看来很奇怪的是,在指定对象 live timeduration 时非常小心的标准在这里留下了阴影。

谁能解释一下?标准是否保证未捕获异常的堆栈展开?如果是,在哪里?如果不是,为什么?

最佳答案

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 to std::terminate() is implementation-defined.

所以它是实现定义的,否则。

If not, why?

如果发生未捕获的异常,标准会调用 std::terminate。这代表程序执行的结束。如果您有某种特定于平台的方式来记录有关当时系统状态的信息,您可能不希望该状态受到堆栈展开的干扰。

如果你不这样做......那么你不管用哪种方式。

如果您确实需要始终展开堆栈,那么您可以将您的 main 代码(以及任何线程函数)放在 try {} catch(...) {throw ;} block 。

关于c++ - c++ 标准是否保证堆栈展开并出现异常?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39962999/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com