AVR Libc Home Page | ![]() |
AVR Libc Development Pages | |||
Main Page | User Manual | Library Reference | FAQ | Example Projects |
Functions | |
int | setjmp (jmp_buf __jmpb) |
void | longjmp (jmp_buf __jmpb, int __ret) __ATTR_NORETURN__ |
C言語は goto ステートメントを忌み嫌ってきたため、goto 命令は同一のローカル関数内だけで使われることになっていました。他の(ローカルでない)関数にジャンプするためには、Cライブラリは関数 setjmp() 、longjmp() を提供しています。setjmp() 、 longjmp() はエラー取扱や割り込みやローレベル処理のサブルーチンなどに有用です。
longjmp() はグローバルレジスタ変数に対してなされた変更を破壊する可能性があります。(参照: How to permanently bind a variable to a register?).
Example:
#include <setjmp.h> jmp_buf env; int main (void) { if (setjmp (env)) { ... ハンドルエラー処理 ... } while (1) { ... メインプロセスのループ。この中のあちこちから foo() を呼んでいる ... } } ... void foo (void) { ... あれこれ処理 ... if (err) { longjmp (env, 1); //エラーになったら、関数foo呼び出し元ではなく、setjmp(env)の所に飛ぶ } }
void longjmp | ( | jmp_buf | __jmpb, | |
int | __ret | |||
) |
あらかじめ保存されたスタック状況へジャンプする
#include <setjmp.h>
longjmp()は最後に呼ばれた setjmp()で保存された環境(jmpbが一致している必要がある)を復帰させます。
longjmp()終了時、プログラムはあたかも 対応する setjmp() が返り値 __ret
をもって帰ってきたかのような挙動を示します。
※使用手順:
※スタック状況保存変数 jmp_buf env; を確保
※メインループに入る前に、まずはsetjmp(env)を実行して、longjmp()の飛び先を変数envに保存(setjmp()の場所になる)
※エラーが起こったら一度最初からやり直したいという場所に、
if (エラー状況) longjmp(env,エラーコード);を置く
※プログラムはsetjmpのある場所に飛び、setjmpがエラーコードを返すという形で続行される。必要ならこの返り値で適切な処理を行う
int setjmp | ( | jmp_buf | __jmpb | ) |