2009-09-03 9 views
32

linux/gccのC++でlongjmpとsetjmpを使うのは安全ですか?C++:longjmpとsetjmpを安全に使用できますか?

  1. (私は効果のlongjmp/setjmp関数は、標準の例外処理になりますどのような側面を知りたい。longjmpの/ setjmp関数を使用して例外処理を実装していないよ)例外処理
  2. *thisポインタ
  3. シグナル
  4. スマートポインタ(ブーストの共有ポインタと侵入ポインタ)
  5. あなたが考えることができる他の何か。

答えて

54

setjmp()/longjmp() RAII(一般的にはデストラクタ)だけでなく、例外処理や例外処理を完全に無効にします。

規格における「その他のランタイムサポート」18.7/4:

任意自動オブジェクトを呼び出し、次に、プログラム内の別の(宛先)点に 制御を移すスローされた例外によって破壊される場合コントロールを同じ(宛先)ポイントに転送するスローポイントでlongjmp(jbuf, val)に移動すると、未定義の動作が発生します。

したがって、最終的にはsetjmp()/longjmp()はC++でうまく再生されません。

+0

longjmpが明示的なメモリ削除とデストラクタでどのように混乱するか説明できますか? – jameszhao00

+12

一般に、C++でスコープを終了する方法がある場合(return、throwなど)、コンパイラはそのブロックを終了した結果破壊される必要がある自動変数のdtorsを呼び出すよう指示します。 'longjmp()'はコード内の新しい場所にジャンプするだけなので、dtorsを呼び出す機会はありません。標準はそれよりも具体的ではありません。標準ではdtorsは呼び出されないとは言わず、すべての賭けはオフになっています。この場合、特定の動作に依存することはできません。 –

+0

私はあまりにもスマートなポインタに精通していない。スタックにスマートポインタがある場合、longjmpを実行すると、スマートポインタはrefcountを削除しません。また、例外を無効にしてlongjmpで狂っていないコードを書くと安全ですか? – jameszhao00

-8

私はこれらのコマンドについてしか学習しておらず、実際のアプリケーションで実際に動作することはありませんでした。

IMHO、これらのAPIを使用するのは安全ではないと言うのは安全です。開発者はこれらの「非公式」なAPIが何をするのか理解できません。

+3

これはコルーチンの実装のためのものです(ランダムにジャンプする必要があります) – jameszhao00

+11

経験豊かな開発者は、これらの「人気のない」APIの機能を絶対に知っています。彼らは何十年もの間、標準Cライブラリの一部となっています。 – Novelocrat

+23

経験豊かな開発者は、これらの機能が果たす役割を絶対に知っています。彼らはまた、C言語(時には必要な場合もある)で使用するのは難しいことであり、C++では非常に危険であることも知っています。 –

5

これはLinuxまたはgccに固有のものではありません。 setjmp/longjmpとC++は、longjmpを使用してデストラクタに自動変数があるコンテキストを残しておけば、あまりうまく動作しません。

デストラクタが実行されず、メモリリークやその他の動作不良が発生する可能性があります。

関連する問題