13

Visual C++ に焦点を当てます。スローしない仕様を使用してthrow()(つまり) C++ コードで大幅なパフォーマンスの向上を経験したことがありますか? __declspec(nothrow)それは本当にオプティマイザーに役立ちますか? パフォーマンスの向上を示すベンチマークはありますか?

インターネットで別の (反対の) アドバイスを見つけました。

ブーストの例外仕様の理論的根拠に反対 throw()です。代わりに、Larry Ostermanは彼のブログ投稿でそれを支持しているようです: Why add a throw() to your methods?

(私は VC++ 固有のコードに興味があることを明確にしたいと思いthrow()ます。GCC では、ランタイム チェックのために仕様が実際には「ペシミゼーション」になる可能性があることを知っています。)

PS ATLヘッダーを読んで、広く使用されていることがわかりましたthrow()さらに、この MSDN の記事で、同様に仕様を使用する便利な C++ RAIIunique_handleクラスを見つけました。throw()

4

3 に答える 3

4

MSVC コンパイラはそれを最適化のヒントとして扱います。

Boost はクロスプラットフォームである必要があり、さまざまなコンパイラで安全かつ効率的なものを使用する必要があります。また、boost のドキュメントにあるように、一部のコンパイラは が指定されている場合により遅いコードを生成する可能性がthrow()あり、多くの場合、コンパイラは指定の有無に関係throw()なく例外がスローされないと推測できるため、Boost の場合、最も安全な方法は決して使用しないことです。スロー仕様。

ただし、特に MSVC をターゲットにしている場合throw()は、関数の例外処理コードを生成しないようにコンパイラに効果的に指示します。これにより、関数が複雑すぎてコンパイラが例外をスローできないと判断できない場合に、速度が向上する可能性があります。

于 2012-05-12T09:49:38.130 に答える
1

私はそれを追加しますが、オプティマイザーがより正しいコードを書くのを助けるためではありません。

class X
{
    public:
        void swap(X& rhs) throw(); // Swap better not ever throw
                                    // If it does there is something else
                                    // much more seriously wrong
};
于 2012-05-12T08:08:44.430 に答える
1

の主な問題throw()は、としてマークされた関数内のコードがスローされるthrow() 可能性があることです。たとえば、これは完全に機能します。

void foo() throw()
{
    throw "haha\n";
}

int main()
{
    try {
        foo();
    }
    catch(const char* s) {
        std::cout << s;
    }
    return 0;
}

throw当然のことながら、 foo はtoにならないことに注意してくださいmain。そして、例外をキャッチしません(throw()指定子をコメントするかのように)。代わりに、コンパイラはコード関数をtry{}catch()ブロックでラップします。例外が生成されると、グローバル ハンドラによって処理されます (これは、デフォルトでプログラムがクラッシュすることを意味します)。

コンパイラーは、内部コードが例外を生成する可能性がないことを確信していない限り、関数コードをブロックでラップする必要があることに注意してください。try{}cath()

その結果、 の呼び出し元である程度の最適化をfoo行うことができますが、の内部 fooでは事態がより複雑になります。

編集:

__declspec(nothrow)は異なります: Microsft が言うように、

この属性は、宣言された関数とそれが呼び出す関数が決して例外をスローしないことをコンパイラに伝えます。

つまり、コンパイラはtry{}catch()ラッパー コードを省略できます。

EDIT2 実際、Microsoft は標準の動作に違反しており、throw(). それでは、throw()パフォーマンスを向上させるために使用できます。

于 2012-05-12T10:26:23.667 に答える