_longjmp() - 非ローカル goto

標準

標準/拡張機能 C/C++ 依存項目

XPG4.2
Single UNIX Specification、バージョン 3

両方  

形式

#define _XOPEN_SOURCE_EXTENDED 1
#include <setjmp.h>

void _longjmp(jmp_buf env, int value);

機能説明

_longjmp() 関数は、以前 _setjmp() によって env に 保管されているスタック環境を復元します。_setjmp() 関数と _longjmp() 関数は、非ローカル goto の実行方法を提供します。これらは、シグナル・ハンドラーでよく使用されます。

_setjmp() の呼び出しにより、現行のスタック環境が env に 保管されます。

後続の _longjmp() 呼び出しにより、保管されている環境が復元され、プログラム内の _setjmp() 呼び出しに対応する位置へ制御が戻されます。_setjmp() 呼び出しによって値引数の指定 value が 戻されたかのように、実行が再開されます。制御を受け取る関数へ アクセスできるすべての変数には、_longjmp() が呼び出されたときに 設定されていた値が入ります。レジスター変数の値は、予測不可能です。 _setjmp() および _longjmp() の間の呼び出しで変更される、非揮発性 auto 変数も予測不可能です。

X/Open 規格では、_longjmp() および _setjmp は、機能的にそれぞれ longjmp() および setjmp() と同等ですが、追加の制限として、_longjmp() および _setjmp() はシグナル・マスクを操作できないという記述が あります。ただし、このインプリメンテーションでは、longjmp() および setjmp() は、シグナル・マスクを操作しません。したがって、この場合、_longjmp() および _setjmp() は、それぞれ longjmp() および setjmp() と同等になります。

シグナル・マスクをインクルードするスタック環境の保管および復元を行うには、_setjmp() の代わりに sigsetjmp() と siglongjmp() か、もしくは setjmp() と longjmp() を使用してください。

_setjmp() と _longjmp() の対、setjmp() と longjmp() の対、sigsetjmp() と siglongjmp() の対、および getcontext() と setcontext() の対を混用することはできません。_setjmp() によって保管されたスタック環境は、_longjmp() によってのみ復元できます。

注 :
  1. ただし、このインプリメンテーションでは、_setjmp() と _longjmp() の 対は、setjmp() と longjmp() の対と機能的には同一なので混用することは可能ですが、お勧めできません。
  2. _setjmp() を呼び出す関数が、対応する _longjmp() 関数を呼び出す前に 、戻らないことを確認してください。_setjmp() を呼び出す関数が戻った後に _longjmp() を呼び出すと、予測できないプログラムの動作が引き起こされます。
  3. XPLink ルーチンにジャンプして戻るために _longjmp() を使用すると、それより前の _setjmp() (または setjmp()、sigsetjmp()、getcontext()、など) が呼び出された後、および _longjmp() が呼び出される前に、XPLink ルーチンによって発行されたすべての alloca() 要求は、バックアウトされます。これらの alloca() 要求によって取得されたすべてのストレージは、XPLink ルーチンが再開される前に解放されます。
  4. 非 XPLink ルーチンにジャンプして戻るために _longjmp() を使用すると、_setjmp() (その他) の後および _longjmp() の前に発行された alloca() 要求は、バックアウトされません。
_longjmp() に渡される value 引数はゼロ以外で なければなりません。value に 0 引数を指定しても、その値は _longjmp() により 1 に置換されます。
env
jmp_buf 構造体のアドレス。
value
_setjmp() からの戻り値。

SC++ の特殊な動作: _setjmp() と _longjmp() を使用して z/OS® XL C++ プログラム内の制御権を移動する場合、自動オブジェクトの破壊に関する動作は未定義です。さらに、プログラム内で他の (宛先) ポイントに制御権を移動する例外がスローされたことによって、自動オブジェクトが破棄された場合、その同じ (宛先) ポイントに制御権を移動するスロー・ポイントで _longjmp() を呼び出す動作は未定義です。これは、z/OS XL C++z/OS XL C/C++ の両方の ILC モジュールに当てはまります。_setjmp() と _longjmp() の、try()、catch()、および throw() との併用も未定義です。

XPLINK コンパイル C++ の特殊な動作: setjmp.h および ucontext.h に関連する制約事項は、以下のとおりです。
  1. Language Environment® のリリース 10 以降のライブラリーを使用して実行され、 jmp_bufsigjmp_buf、または ucontext_t の型を使用する、リリース 10 以降の C コンパイラーでコンパイルされたすべての XPLINK プログラムは、Language Environment 2.9 以前の C ヘッダーを付けてコンパイルすることはできません。
  2. いずれかのレベルの Language Environment ヘッダーを付けてコンパイル された XPLINK 以外の関数は、jmp_bufsigjmp_buf、または ucontext_t のデータ項目を定義してはならず、これらの渡されたデ ータ項目をもった getcontext()、 longjmp()、_longjmp()、setjmp()、_setjmp()、setcontext()、sigsetjmp()、または swapcontext() を呼び出す XPLINK 関数に、それ らのデータ項目を渡すことはできません。
  3. __XPLINK__ が定義されると、リリース 10 およびそれ以降のヘッダーは、setjmp()、getcontext()、および関連した関数が XPLINK ルーチンから呼び出される際に、これらの関数によって必要とされるより大きな jmp_bufsigjmp_buf、または ucontext_t の領域を定義します。__XPLINK__ が定義されないと、リリース 10 およびそれ以降のヘッダーは、より小さい jmp_bufsigjmp_buf、または ucontext_t の領域を定義します。リリース 10 より前の Language Environment ヘッダーも、これらのデータ域のよ り小さいバージョンを定義します。XPLINK 関数が、小さい jmp_bufsigjmp_buf、または ucontext_t の領域を 指定して setjmp()、getcontext()、または類似の関数を呼び出す場合、渡された (小さすぎる) データ域の終端を超えて C ライブラリーを保管しようとすると、ストレージ・オーバーレイまたはプログラム・チェックが発生する場合があります。

戻り値

_longjmp() は、普通の関数呼び出しや戻りメカニズムを使用しません。したがって、戻り値はありません。_longjmp() が完了すると、対応する _setjmp() の呼び出しが value で指定された値を 戻したかのように、プログラムの実行が継続されます。

関連情報