プログラマーC ++、Java、C#...「純粋な」Cでコードを記述するとき、例外メカニズムがないという問題にしばしば直面します。 Cでエラーを処理する古典的な方法は、戻りコードをチェックすることです。 ネストが深い複雑なアルゴリズムでは、これは非常に不便です。 以下の方法は新しいものではありませんが、残念ながら多くの人は慣れていません。
そのため、POSIXにはいくつかの便利な関数があります:
setjmpと
longjmp #include <setjmp.h>
int setjmp(jmp_buf env);
void longjmp(jmp_buf evn、int val);
例を考えてみましょう:
#include <setjmp.h>
jmp_buf jbuf;
/ * ...... * /
/ *ハンドラーを配置します* /
int result = setjmp(jbuf);
スイッチ(結果){
ケース0:/ *これはtryブロックです* /
ケース1:/ * catchブロックの1つ* /
ケース2:/ *別の問題* /
};
/ * .... * /
/ *ここで例外をスローしたい* /
longjmp(jbuf、EXCODEコード);
setjmp呼び出しは、スタックの状態を変数に保存します。 保存すると、setjmpは0を返します。この変数は、遷移をトリガーするコードで使用可能にする必要があります。 longjmpの出力後、すべてがsetjmpが0以外の値を返したように見えます。
注目に値するもの:
1)longjmpは制御を返しません。 setjmpへのロールバックがあるか、jmp_bufが壊れている場合-セグメンテーションエラー。
2)2番目のパラメーターlongjmpは、スタックが復元されたときにsetjmpが返す値です。 0は送信できません(この場合、1が返されます)。
3)上記のメカニズムは、Cのプログラムの「通常のロジック」を壊します。さらに、場合によっては、プログラムをより読みやすくすることができます。 これはgotoのように扱う必要があります。
mralephからのコメントの更新:厳密に言えば、setjmpは「スタック状態」を保存しません。 レジスタ値のみを保存するため、作成された関数が終了した場合は特にjmp_bufは使用できません...