Cライブラリマクロ -setjmp()
setjmp()は C 標準ライブラリ<setjmp.h>内のマクロであり、現在のプログラムの実行状態を保存し、後で longjmp によってlongjmp()その状態に戻るために使用されます。
Cライブラリマクロint setjmp(jmp_buf environment):ローカルの jmp_buf バッファを作成して初期化し、将来この場所にジャンプして戻るために使用します。このサブルーチンは、プログラムの呼び出し環境を env パラメータが指すバッファに保存します。env は longjmp によって使用されます。setjmp を直接呼び出して戻った場合、setjmp は 0 を返します。longjmp によって復元されたプログラム呼び出し環境から戻った場合、setjmp は非ゼロ値を返します。
宣言
以下は setjmp() マクロの宣言です。
#include <setjmp.h> int setjmp(jmp_buf env);
引数
env:jmp_buf 型のjmp_buf変数で、現在のプログラムの実行状態を保存するために使用されます。
戻り値
- もし
setjmp()setjmp を直接呼び出した場合、戻り値は 0 です。 - もし
setjmp()longjmp を介したlongjmp()呼び出しから戻った場合、戻り値はlongjmp()longjmp によって設定された非 0 の値です。
例
以下の例は setjmp() マクロの使い方を示しています。
例
#include <stdio.h>
#include <setjmp.h>
static jmp_buf buf;
void second(void) {
printf("second\n"); // 出力
longjmp(buf,1); // setjmp の呼び出し箇所にジャンプして戻る - setjmp の戻り値を 1 にする
}
void first(void) {
second();
printf("first\n"); // この行は実行されない
}
int main() {
if ( ! setjmp(buf) ) {
first(); // この行に入る前、setjmp は 0 を返す
} else { // longjmp がジャンプして戻ると setjmp は 1 を返すため、この行に入る
printf("main\n"); // 出力
}
return 0;
}
上記のプログラムをコンパイルして実行してみましょう。次の結果が生成されます。
second main
使用場面
- エラー処理と例外処理:
setjmp()とlongjmp()シンプルなエラー処理および例外処理のメカニズムを実装するために使用できます。 - ステートマシン:ステートマシンの状態遷移では、異なる状態の間をジャンプする必要がある場合があります。
setjmp()とlongjmp()このような状態遷移の実装に使用できます。 - シグナル処理と組み合わせて使用する:いくつかの特別な状況では、
setjmp()とlongjmp()シグナルハンドラから抜け出すために使用できます。
注意事項
- setjmp と longjmp の使用
setjmp()とlongjmp()には細心の注意が必要です。これらはプログラムの制御フローを非常に混乱させ、コードの理解やデバッグが困難になるからです。 - マルチスレッドやシグナルハンドラを扱う環境での使用は避けてください。
setjmp()とlongjmp()未定義の動作を引き起こす可能性があるためです。
まとめ
setjmp()とlongjmp()setjmp と longjmp は、プログラムの異なる部分間でジャンプできる非常に柔軟なメカニズムを提供します。特定の状況での制御フローの変更には非常に有用ですが、潜在的な問題や未定義の動作を避けるために、実際に使用する際は注意深く行う必要があります。
C標準ライブラリ - <setjmp.h>