46

Scott Meyers の新しい C++11 ブックからの次のドラフトには、次のように書かれています (2 ページ、7 ~ 21 行)。

コール スタックの巻き戻しと、場合によっては巻き戻しの違いは、コード生成に驚くほど大きな影響を与えます。noexcept 関数では、オプティマイザは、例外が関数の外に伝播する場合にランタイム スタックを巻き戻し可能な状態に保つ必要はありません。また、例外が関数を離れた場合に、noexcept 関数内のオブジェクトが構築の逆の順序で破棄されることを保証する必要もありません。 . その結果、noexcept 関数の本体内だけでなく、関数が呼び出されるサイトでも最適化の機会が増えます。このような柔軟性は、noexcept 関数に対してのみ存在します。「throw()」例外仕様を持つ関数には、例外仕様がまったくない関数と同様に、それがありません。

対照的に、「C++ パフォーマンスに関するテクニカル レポート」5.4のセクションでは、例外処理を実装する「コード」および「テーブル」の方法について説明しています。特に、「table」メソッドは、例外がスローされず、スペースのオーバーヘッドのみがある場合、時間のオーバーヘッドがないことが示されています。

私の質問はこれです - Scott Meyers が巻き戻しとおそらく巻き戻しについて話しているとき、どのような最適化について話しているのですか? これらの最適化が適用されないのはなぜthrow()ですか? 彼のコメントは、2006 年の TR で言及されている「コード」メソッドにのみ適用されますか?

4

4 に答える 4

13

noexceptとの違いは、例外スタックがまだアンワインドされthrow()ている場合にthrow()デストラクタが呼び出されるため、実装はスタックを追跡する必要があることです (15.5.2 The std::unexpected() function標準を参照)。

逆に、std::terminate()はスタックをアンワインドする必要はありません (が呼び出される前にスタックがアンワインドされるかどうかは実装定義であると15.5.1述べています)。std::terminate()

GCC は実際にはスタックを巻き戻していないようですnoexcept: Demo
clang が巻き戻し中: Demo

(デモでf_noexcept()コメントしたりコメントを外したりして、GCC と clang の両方でスタックがアンワインドされることを確認できます)f_emptythrow()throw()

于 2014-09-28T00:03:06.653 に答える