ヘッダー<setjmp.h>
では、マクロ setjmp を定義し、通常の関数呼び出しと戻りの規律を回避するための 1 つの関数と 1 つの型を宣言しています[1]。
型
編集- jmp_buf
- 呼び出し環境を復元するために必要な情報を保持するのに適した配列型です。
- setjmp マクロの呼び出し環境は、longjmp 関数の呼び出しで実行を元に戻すのに十分な情報で構成されています。
- longjmp 関数を呼び出して正しいブロックに実行を戻し、そのブロックを再帰的に呼び出すのに十分な情報で構成されます。
- 再帰的に呼び出された場合、longjmp関数の呼び出しに十分な情報で構成されます。
- これには、浮動小数点のステータスフラグの状態、開いているファイルの状態、抽象機械の他のコンポーネントの状態などは含まれません。
- 抽象機械の他のコンポーネントの状態は含まれません。
関数・マクロ
編集setjmpがマクロであるか、外部リンクで宣言された識別子であるかは不詳です。 もし マクロ定義が実際の関数にアクセスするために抑制されている場合や、プログラムがsetjmpという名前の外部識別子を定義している場合、 プログラムがsetjmpという名前の外部識別子を定義した場合、その動作は未定義です。
これらの関数は、プログラムの低レベル関数で発生する異常な状態に対処するのに便利です。
呼び出し環境の保存
編集- 形式
#include <setjmp.h> int setjmp(jmp_buf env);
- Description
- setjmp マクロは、その呼び出し環境を jmp_buf 引数に保存し、後で longjmp 関数で使用できるようにします。
- 戻り値
- 戻り値が直接呼び出しの場合、setjmp マクロは値 0 を返します。戻り値がlongjmp関数の呼び出しの場合、setjmpマクロはゼロ以外の値を返します[2]。
- 環境制限
- setjmp マクロの呼び出しは、以下のコンテキストのいずれかでのみ現れるものとする。
- 選択文または反復文の制御式全体。
- 関係演算子または等式演算子の一方のオペランドと、もう一方のオペランドが整数の定数式の場合。演算子の一方のオペランドに整数の定数を指定し、その結果の式が選択文または反復文の制御式全体となる場合。の制御式全体となる。
- 単項の!演算子のオペランドで、その結果の式が選択文または反復文の制御式全体となるもの。単項演算子のオペランドで、結果として選択文または反復文の制御式全体となるもの.
- 式文の式全体(場合によってはvoidにキャストされる)。
- その他の文脈で呼び出された場合、その動作は未定義です。
呼び出し環境の復元
編集- 形式
#include <setjmp.h> _Noreturn void longjmp(jmp_buf env, int val);
- Description
- longjmp 関数は、setjmp マクロの直近の呼び出しによって保存された環境を、対応する jmp_buf 引数を持つプログラムの同じ呼び出しで復元します。
- そのような呼び出しが行われていない場合、呼び出しが他のスレッドから行われた場合、setjmp マクロを呼び出した関数がその間に実行を終了した場合。または、setjmp マクロの呼び出しが可変的に変更された型を持つ識別子のスコープ内にあり、その間に実行がそのスコープを離れた場合、その動作は未定義です。
- アクセス可能なオブジェクトはすべて値を持ち、抽象機械の他のコンポーネントはすべて状態を持ちます。
- longjmp関数が呼び出された時点で、すべてのアクセス可能なオブジェクトは値を持ち、抽象機械の他のすべての構成要素は状態を持ちます。
- 対応するsetjmpマクロの呼び出しを含む関数にローカルな、自動保存のオブジェクトの値は除きます。ただし、対応するsetjmpマクロを呼び出した関数のローカルにある自動保存期間のオブジェクトで、volatile修飾された型を持たず、setjmpの呼び出しと longjmpの呼び出しの間に変更されたvolatile-qualified typeを持たない対応するsetjmpマクロの呼び出しを含む関数のローカルなオブジェクトの自動記憶期間の値は不確定です。
- 戻り値
- longjmp が完了した後、スレッドの実行は、対応する setjmp マクロの呼び出しが val で指定された値を返したかのように継続されます。
- longjmp関数は、setjmpマクロに値0を返させることはできません。valが0の場合、setjmpマクロは値1を返します。
- 例
#include <setjmp.h> jmp_buf buf; void g(int n); void h(int n); int n = 6; void f(void) { int x[n]; // valid: f is not terminated setjmp(buf); g(n); } void g(int n) { int a[n]; // a may remain allocated h(n); } void h(int n) { int b[n]; // b may remain allocated longjmp(buf, 2); // might cause memory loss }
脚註
編集- ^ N2596 working draft — December 11, 2020 ISO/IEC 9899:202x (E). ISO/IEC JTC1/SC22/WG14. p. 240, §7.13 Nonlocal jumps <setjmp.h> .
- ^ forkと同じファシリティです。
参考文献
編集- 国際標準化機構/国際電気標準会議 ISO/IEC 9899:2018(en) Information technology — Programming languages — C(2018-07-05)