为什么析构函数不会被异常调用?

Con*_*tin 50 c++ destructor exception stack-unwinding visual-c++

我希望A::~A()在这个程序中被调用,但它不是:

#include <iostream>

struct A {
  ~A() { std::cout << "~A()" << std::endl; }
};

void f() {
  A a;
  throw "spam";
}

int main() { f(); }
Run Code Online (Sandbox Code Playgroud)

但是,如果我将最后一行更改为

int main() try { f(); } catch (...) { throw; }
Run Code Online (Sandbox Code Playgroud)

然后A::~A() 称为.

我正在从Visual Studio 2005编译"Microsoft(R)32位C/C++优化编译器版本14.00.50727.762 for 80x86".命令行是cl /EHa my.cpp.

编译器像往常一样吗?标准对此事有何评价?

lef*_*cus 65

不会调用析构函数,因为在堆栈展开之前会调用未处理异常的terminate().

C++规范所说的具体细节不在我的掌握之中,但是使用gdb和g ++的调试跟踪似乎证实了这一点.

根据标准草案第15.3 条草案 9:

9 If no matching handler is found in a program, the function terminate()
  (_except.terminate_)  is  called.  Whether or not the stack is unwound
  before calling terminate() is implementation-defined.

  • Upvote 引用官方标准文档。 (2认同)

Ale*_*Che 15

C++语言规范声明: 为从try块到throw-expression的路径构造的自动对象调用析构函数的过程称为"堆栈展开". 您的原始代码不包含try块,这就是为什么不会发生堆栈展开的原因.