longjmp() — スタック環境の復元

形式

#include <setjmp.h>
void longjmp(jmp_buf env, int value);

言語レベル

ANSI

スレッド・セーフ

はい

説明

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

setjmp() 関数を呼び出すと、現行のスタック環境が envに保管されます。 その後 longjmp() を呼び出すと、保管された環境が復元され、 setjmp() 呼び出しに対応するプログラム内のポイントに制御が戻されます。 setjmp() 呼び出しが指定の valueを戻したかのように、処理が再開されます。

制御を受け取る関数で使用可能なすべての変数 (レジスター変数を除く) には、 longjmp() が呼び出されたときの値が含まれています。 レジスター変数の値は、予測不可能です。 setjmp() 関数と longjmp() 関数の間で変更される不揮発性 auto 変数も、予測不能です。
注: setjmp() 関数を呼び出す関数が、対応する longjmp() 関数を呼び出す前に戻らないことを確認してください。 setjmp() 関数を呼び出した後に longjmp() を呼び出すと、予測不能なプログラム動作が発生します。

引数 value は非ゼロでなければなりません。 valueにゼロ引数を指定すると、 longjmp() は代わりに 1 を使用します。

戻り値

longjmp() 関数は、通常の関数呼び出しおよび戻りメカニズムを使用しません。戻り値はありません。

この例では、下のステートメントで、スタック環境を保存します。
   if (setjmp(mark) != 0) ...
システムは、 if ステートメントを最初に実行するときに、環境を mark に保管し、条件を FALSE に設定します。これは、 setjmp() 関数が環境を保管するときに 0 を戻すためです。 プログラムで次のメッセージが出力されます。
   setjmp has been called

後続の関数 p() の呼び出しにより、 longjmp() 関数が呼び出されます。 mark 変数に保管されている環境を使用して setjmp() 関数を呼び出した直後に、 main() 関数内のポイントに制御が移ります。 今回は、-1がスタックに置かれる戻り値としてlongjmp()関数呼び出しの第2パラメータに指定されているので、条件はTRUEとなる。 次に、この例では、ブロック内のステートメントを実行し、「longjmp() has been called」というメッセージを出力し、 recover() 関数を呼び出して、プログラムを終了します。

#include <stdio.h>
#include <setjmp.h>
#include <stdlib.h>
 
jmp_buf mark;
 
void p(void);
void recover(void);
 
int main(void)
{
   if (setjmp(mark) != 0)
   {
      printf("longjmp has been called\n");
      recover();
      exit(1);
      }
   printf("setjmp has been called\n");
   printf("Calling function p()\n");
   p();
   printf("This point should never be reached\n");
}
 
void p(void)
{
   printf("Calling longjmp() from inside function p()\n");
   longjmp(mark, -1);
   printf("This point should never be reached\n");
}
 
void recover(void)
{
   printf("Performing function recover()\n");
}
/*******************Output should be as follows: **********************
 setjmp has been called
 Calling function p()
 Calling longjmp() from inside function p()
 longjmp has been called
 Performing function recover()
**********************************************************************/

関連情報