C リファレンス マニュアルの付録 B では、2 つの関数setjmp
と、非ローカル ジャンプlongjmp
と呼ばれるものについて説明しています。状態情報を保存し、longjmp が を復元するという基本的な理解は別として、この機能の正確なフローと使用例を理解できていません。setjmp
state
では、この機能は正確には何を達成し、どこで役立つのでしょうか?
制御フローに関しては、setjmp
2 回返され、longjmp
決して返されません。setjmp
環境を保存するために初めて呼び出すと、ゼロが返されます。 を呼び出すlongjmp
と、制御フローは fromsetjmp
に渡され、引数に指定された値が返されます。
(実際には関数である必要はないことに注意してくださいsetjmp
。マクロであってもかまいませんlongjmp
。しかし、は関数です。)
ユースケースは、一般に「エラー処理」および「これらの関数を使用しない」として引用されます。
制御フローの例を次に示します。
jmp_buf env;
void foo()
{
longjmp(&env, 10); +---->----+
} | |
| |
int main() (entry)---+ ^ V
{ | | |
if(setjmp(&env) == 0) | (= 0) | | (= 10)
{ | ^ |
foo(); +---->----+ |
} +---->----+
else |
{ |
return 0; +--- (end)
}
}
ノート:
に 0 を渡すことはできませんlongjmp
。その場合、1
によって返されsetjmp
ます。
setjmp
対応する の前に呼び出した関数から戻ってはなりませんlongjmp
。つまり、コール スタックの上longjmp
でのみ呼び出す必要があります。 setjmp
(@wildplasser に感謝:)の結果を実際に保存setjmp
することはできません。switch
ただし、いくつかの異なる方法で戻りたい場合は、 a を使用できます。
switch (setjmp(&env))
{
case 0: // first call
case 2: // returned from longjmp(&env, 2)
case 5: // returned from longjmp(&env, 5)
// etc.
}