在 [except.ctor] 中,标准文件 (N4140) 保证:
...自从进入 try 块开始构造的所有自动化对象都将调用析构函数...
然而,在下面的示例中,空的输出证明了函数 foo
的返回值没有被析构,尽管它已经被构造。编译选项为 -O0 -fno-elide-constructors -std=c++14
,使用 g++ (5.2.1) 和 clang++ (3.6.2-1)。
struct A { ~A() { cout << "~A\n"; } };
struct B { ~B() noexcept(false) { throw 0; } };
A foo() {
B b;
return {};
}
int main() {
try { foo(); }
catch (...) { }
}
这是g++和clang++都存在的一个bug吗?还是函数返回值不被视为自动对象,或者这是C++语言中的一个漏洞?在[stmt.return]、[expr.call]或[dcl.fct]中,我没有找到明确说明函数返回值是否被视为自动对象的语句。我所找到的最接近的提示是6.3.3 p2:
...return语句可能涉及临时对象的构造、复制或移动...
以及5.2.2 p10:
如果结果类型是左值引用类型或对函数类型的右值引用,则函数调用是左值;如果结果类型是对象类型的右值引用,则函数调用是xvalue;否则是prvalue。