C リファレンス マニュアルの付録 B では、2 つの関数setjmpと、非ローカル ジャンプlongjmpと呼ばれるものについて説明しています。状態情報を保存し、longjmp が を復元するという基本的な理解は別として、この機能の正確なフローと使用例を理解できていません。setjmpstate
では、この機能は正確には何を達成し、どこで役立つのでしょうか?
制御フローに関しては、setjmp2 回返され、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.
}