【書式】
#include <setjmp.h>
int setjmp(jmp_buf env);
void longjmp(jmp_buf env, int val);
【解説】
setjmp(), longjmp()は、関数呼び出しが何重にも入れ子になっているとき
に、いっきに上位の関数に戻るときに使います。
まずジャンプ先の場所でsetjmp()を呼んでjmp_buf型変数envにその時点の環
境およびジャンプ先の番地をセーブしておきます。
そして、 ジャンプしたい場所では、 ジャンプ先の環境がセーブされている
env をパラメタとしてlongjmp()を呼びます。この時、valにセットした値が
setjmp()の返す値になります。
longjmp()を通してsetjmp()からリターンしてきた場合、 レジスタ変数の値
は不定となりますので注意してください。LSI C-86ではローカル変数はデフ
ォルトでレジスタ変数となりますので、特に注意が必要です。setjmp()を呼
び出す関数のローカル変数はvolatile指定をして、レジスタ変数とならない
ようにしてください。
【使用例】
jmp_buf env;
int val(char **s)
{
if (! isdigit(**s)) {
fprintf(stderr, "missing number\n");
longjmp(env, 1);
}
return (strtol(*s, s, 10));
}
void bar(char *s)
{
int v;
v = val(&s);
switch (*s++) {
case '+': return (v + val(&s));
case '-': return (v - val(&s));
case '*': return (v * val(&s));
case '/': return (v / val(&s));
default:
fprintf(stderr, "illegal operation\n");
longjmp(env, 1);
}
}
void main()
{
char line[80];
for (;;) {
printf(">");
gets(line);
if (setjmp(env) == 0)
printf("%d\n", bar(line));
}
}
【リターン値】
setjmp() は最初に呼ばれた時は、 値0を返します。longjmp()が呼ばれた時
は、その引数valがsetjmp()の返す値となります。
ただし、longjmp()でvalに0を渡した場合、setjmp()は1を返します。したが
ってsetjmp()の最初の呼び出しとlongjmp() によるリターンとを確実に区別
することができます。
【可搬性】
ANSI, UNIX, DOS窓
【バグ】
setjmp(), longjmp()は使い方を誤ると危険ですので、次の2点に注意してく
ださい。
+ setjmp()を呼ぶ関数は必ずレジスタ割り付けをしないことを指定してく
ださい
+ setjmp()を呼んでいる関数がreturnした後にlongjmp()を呼ぶと、プロ
グラムは暴走してしまいますので絶対に呼ばないでください
【copyright (c) 安江正樹@東海大学理学部物理学科】