setjmp関数は現在の関数の実行環境を退避します。その後longjmp関数を呼び出すことにより、setjmp関数を呼び出したプログラム上の位置に戻ることができます。
以下にsetjmp、longjmp関数を使用して関数間の制御の移動をサポートした例を示します。
9 printf("return from longjmp\n");
17 printf("subroutine is running \n");
8行目でsetjmp関数を呼んでいます。この時、setjmp関数の呼び出された環境を、jmp_buf型の変数envに退避します。この時のリターン値は0なので、次に関数subが呼び出されます。
関数subの中で呼び出されるlongjmp関数により、変数envに退避した環境を回復します。その結果、プログラムは、あたかも8行目のsetjmp関数からリターンしたかのようにふるまいます。ただし、この時のリターン値はlongjmp関数の第2実引数で指定した値(1)になります。
setjmp関数により退避された実行環境は、longjmp関数において使用されます。
setjmp関数として呼び出された時のリターン値は0ですが、longjmp関数からリターンしてきた時のリターン値は、longjmp関数で指定した第2引数の値となります。
setjmp関数を複雑な式から呼び出す場合、式の評価の途中結果等の現在の実行環境の一部が失われる可能性があります。setjmp関数はsetjmp関数の結果と定数式の比較という形だけで使用し、複雑な式の中では呼び出さないようにしてください。
setjmp関数へのポインタを使った間接呼び出しはしないでください。
setjmp関数で退避していた関数の実行環境を回復し、setjmp関数を呼び出したプログラムの位置に制御を移動します。
void longjmp(jmp_buf env, long ret);
longjmp関数は、同じプログラム中で最後に呼び出されたsetjmp関数によって退避された関数の実行環境を第1引数envで指定された記憶域から回復し、そのsetjmp関数を呼び出したプログラムの位置に制御を移します。この時longjmp関数の第2引数retがsetjmp関数のリターン値として返ります。ただし、retが0の時はsetjmp関数へのリターン値としては1が返ります。
setjmp関数が呼び出されていない時、あるいはsetjmp関数を呼び出した関数がすでにreturn文を実行している時は、longjmp関数の動作は保証しません。