3

C++ ライブラリへの PERL XS インターフェイスを作成しています。croakライブラリが例外をスローしたときに呼び出す必要があります。

例外ハンドラーで直接実行すると、呼び出しに期待されるように、キャッチされた例外のデストラクタへの呼び出しが失われlongjmpます。例外には解放されない文字列メンバーが含まれているため、これは重要です。

明らかな解決策はcroak、例外がキャッチされた場合、次のように catch ブロックの後に実行することです。

bool do_croak = false;
try {
    throw MyException();
} catch (MyException &e) {
    do_croak = true;
}
if (do_croak)
    croak(NULL);

しかし、私は疑問に思っています:キャッチされた例外のデストラクタを直前に明示的に呼び出すだけで十分でしょうlongjmpか? このような:

try {
    throw MyException();
} catch (MyException &e) {
    e.~MyException();
    croak(NULL);
}
4

1 に答える 1

4

longjmpC++ プログラムで安全に使用することはほとんど不可能です。具体的には:

C++11 18.10/4: andをand で置き換えた場合、 setjmp/longjmp呼び出しのペアは未定義の動作をし、任意の自動オブジェクトに対して非自明なデストラクタを呼び出します。setjmplongjmpcatchthrow

この場合、 から例外をスローするcroakと のデストラクタが呼び出されるため、そこからe呼び出すとlongjmp未定義の動作が発生します。デストラクタを自分で呼び出すと、動作がさらに不明確になります。

于 2013-03-28T16:37:02.433 に答える