-2

を使用することの危険性について同僚と議論していました。catch(...)

彼は、管理されていない例外の原因を特定するのに役立つように、トレース/ログが続くことを厳密に暗示して、可能な用途を指摘していました。catch(...)

私は個人的にそれについてかなり懐疑的です。の明確な安全な使用法について知っていますか?catch(...)

編集: 議論に興味がある人のために、私の同僚がProgrammers サイトでこの質問を指摘してくれました。

4

3 に答える 3

5

catch(...)私が知っているの最も明確で興味深い安全な使用法は、さまざまな例外を処理するためのコードを共有関数にオフロードすることです。

void handle_error() {
    try {
        throw;
    } catch (TiresomelyPedanticException &) {
        # lah lah I don't care
        return;
    } catch (InterestingException &) {
        log_something();
        throw;
    }
    // etc. This catch chain may *or may not* need a catch(...)
    // of its own, it depends whether part of its job is to
    // deal with the "miscellaneous" case.
}

次のように関数を使用します。

try {
    blah();
} catch(...) {
    handle_error();
}

... 何処か別の場所 ...

try {
    something_that_throws_the_same_exceptions_as_blah();
} catch (...) {
    handle_error();
}

ただし、上記のパターンは少し C++03 主義であることが判明する可能性があります。C++11 では、キャプチャ ラムダを記述するのは非常に簡単であるため、呼び出し側にとっては次のような方が便利かもしれませんがcatch(...)、パターンにはありません。

template <typename Func>
auto do_and_handle_error(Func f) -> decltype(f()) {
    try {
        return f();
    } // catch chain goes here
}

次のように使用します。

do_and_handle_error(blah);

blahまたは、引数をとるときに実際に必要であることが判明するように:

do_and_handle_error([&](void) { return blah(arg1,arg2); });

の退屈な使い方は、catch(...)プログラムの終了前にスタックが巻き戻されることを保証することです:

int my_main() {
    RAIIClass some_object_i_want_to_get_destroyed_no_matter_what;
    some_code_that_might_throw();
    return 0;
}

int main() {
    try {
        return my_main();
    } catch (...) {
        throw;
    }
}

some_objectキャッチがない場合、標準は、コードがスローされた場合に破棄されるかどうかにかかわらず、それを未指定または実装定義のままにします。

于 2013-02-07T13:31:41.957 に答える
4

多くの場合、例外は過剰に使用されます。ほとんどの場合、この使いすぎにはキャッチオール ステートメントが伴います。これは通常、例外の不適切な使用と理解の兆候です。私は決してお勧めしません。悲しいことに、私が働いていた (悪い) 場所では、他の人がこの方針を強制していました。

于 2013-02-07T13:32:24.117 に答える
3

以下は常に安全です。

try
{
    some_local_stuff();
}
catch (...)
{
    clean_up_local_stuff();
    throw;
}

つまり、キャッチオールcatchブロックは、まったく同じ例外を再スローするか、例外ポインターを格納して例外を転送する場合にのみ使用する必要があります。

例外を完全になくす catch ブロックは、処理する例外の種類を特定する必要があります。

于 2013-02-07T13:30:47.167 に答える