は標準(N4140は)ことを保証...関数の戻り値は自動オブジェクトなので、破壊されていることが保証されていますか? 【except.ctor]で
...デストラクタはtryブロックが が入力されてから構築 すべての自動オブジェクトに対して呼び出され
しかし、次の例では、空のoutputは、それが構築されているにもかかわらず、関数foo
の戻り値が破棄されないことを示しています。 g ++(5.2.1)とclang ++(3.6.2-1)とオプション-O0 -fno-elide-constructors -std=c++14
を使用してコンパイルされました。
struct A { ~A() { cout << "~A\n"; } };
struct B { ~B() noexcept(false) { throw 0; } };
A foo() {
B b;
return {};
}
int main() {
try { foo(); }
catch (...) { }
}
これは++グラム++にと打ち鳴らすの両方のバグで、または関数の戻り値ではないと考え 自動オブジェクトである、またはそれは、C++言語のループ穴のですか?
[stmt.return]、[expr.call]または[dcl.fct]のいずれも、関数戻り値が自動 オブジェクトと見なされるかどうかを明確に示す が見つかりました。
... return文が 建設に関与してコピーするか、一時的なオブジェクトの移動ができます...
および5.2.2 P10:私が見つけた最も近いヒントは6.3.3 p2としています:
関数呼び出しは、結果タイプは左辺値 参照型またはタイプを機能させる右辺値参照、 結果型は型のオブジェクトへの右辺値参照がある場合はxValueである場合左辺値であり、そしてprvalueさもなければ。
私は、gccとclangの両方がすでに何年も前からこのバグを提起していることを知ったので、すぐに修正するとは思っていません:[gcc](https://gcc.gnu.org/bugzilla/show_bug.cgi ?id = 33799)、[clang](https://llvm.org/bugs/show_bug.cgi?id=12286)。 –
この場合、コンパイラはオブジェクトAの構築を省略できますか?私はRVOに似たいくつかのルールを意味する。 – Mikhail
@Mikhail私はそう信じていない。 RVOは構造を完全に取り除くことはできません。中間構造を取り除くことができます。 – TartanLlama