我希望A::~A()
在这个程序中被调用,但它不是:
#includestruct A { ~A() { std::cout << "~A()" << std::endl; } }; void f() { A a; throw "spam"; } int main() { f(); }
但是,如果我将最后一行更改为
int main() try { f(); } catch (...) { throw; }
然后A::~A()
被称为.
我正在从Visual Studio 2005编译"Microsoft(R)32位C/C++优化编译器版本14.00.50727.762 for 80x86".命令行是cl /EHa my.cpp
.
编译器像往常一样吗?标准对此事有何评价?
不会调用析构函数,因为在堆栈展开之前会调用未处理异常的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.
C++语言规范声明: 为从try块到throw-expression的路径构造的自动对象调用析构函数的过程称为"堆栈展开". 您的原始代码不包含try块,这就是为什么不会发生堆栈展开的原因.