setjmp() — 環境の保存

形式

#include <setjmp.h>
int setjmp(jmp_buf env);

言語レベル

ANSI

スレッド・セーフ

はい

説明

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

setjmp() 関数を呼び出すと、現行のスタック環境が envに保管されます。 それ以降に longjmp() 関数を呼び出すと、保管された環境が復元され、 setjmp() 呼び出しに対応するポイントに制御が戻されます。 制御を受け取る関数で使用可能なすべての変数 (レジスター変数を除く) の値には、 longjmp() 関数が呼び出されたときの値が含まれています。 レジスター変数の値は、予測不可能です。 setjmp() 関数の呼び出しと longjmp() 関数の呼び出しの間に変更される不揮発性 auto 変数も、予測不能です。

戻り値

setjmp() 関数は、スタック環境を保管した後、値 0 を戻します。 setjmp() 関数が longjmp() 呼び出しの結果として戻る場合、 longjmp() 関数の value 引数を戻します。 longjmp() 関数の value 引数が 0の場合は 1 を戻します。 エラーの戻り値はありません。

この例では、下のステートメントで、スタック環境を保存します。
   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()
**********************************************************************/

関連情報