close
名前空間
変種

longjmp

提供: cppreference.com
<tbody> </tbody> <tbody class="t-dcl-rev "> </tbody><tbody> </tbody>
ヘッダ <setjmp.h> で定義
void longjmp( jmp_buf env, int status );
(C11未満)
_Noreturn void longjmp( jmp_buf env, int status );
(C11以上)

setjmp の以前の呼び出しで保存された実行コンテキスト env をロードします。 この関数は戻りません。 制御は env をセットアップした setjmp マクロの呼び出し元に転送されます。 その後 setjmpstatus に渡された値を返します。

setjmp を呼び出した関数が終了していた場合 (return によって、またはスタックのより高い位置への別の longjmp によって)、動作は未定義です。 言い換えると、コールスタックの上方向への longjmp しか許されません。

スレッド間のジャンプ (setjmp を呼んだ関数が別のスレッドで実行されていた場合) も未定義動作です。

(C11以上)

setjmp が呼ばれたとき、 VLA や他の可変修飾型の変数がスコープ内にあって、制御がそのスコープを離れた場合、たとえ制御が関数内に残ったとしても、その setjmp への longjmp は未定義動作を発生させます。

スタックを登るにあたって、 longjmp はいかなる VLA も開放せず、この方法でそれらの生存期間が終了した場合、メモリリークが発生する可能性があります。

void g(int n)
{
    int a[n]; // a may remain allocated
    h(n); // does not return
}
void h(int n)
{
    int b[n]; // b may remain allocated
    longjmp(buf, 2); // might cause a memory leak for h's b and g's a
}
(C99以上)

引数

env - setjmp によって保存されたプログラムの実行状態を参照する変数
status - setjmp から返す値。 0 と等しい場合は、代わりに 1 が使用されます

戻り値

(なし)

ノート

longjmp は、関数が意味のある戻りを行えない、予期しないエラー状況を処理することが意図されています。 これは他のプログラミング言語の例外処理と同様のものです。

#include <stdio.h>
#include <setjmp.h>
#include <stdnoreturn.h>
 
jmp_buf jump_buffer;
 
noreturn void a(int count) 
{
    printf("a(%d) called\n", count);
    longjmp(jump_buffer, count+1); // will return count+1 out of setjmp
}
 
int main(void)
{
    volatile int count = 0; // local vars must be volatile for setjmp
    if (setjmp(jump_buffer) != 9)
        a(count++);
}

出力:

a(0) called
a(1) called
a(2) called
a(3) called
a(4) called
a(5) called
a(6) called
a(7) called
a(8) called

参考文献

  • C11 standard (ISO/IEC 9899:2011):
  • 7.13.2.1 The longjmp macro (p: 263-264)
  • C99 standard (ISO/IEC 9899:1999):
  • 7.13.2.1 The longjmp macro (p: 244-245)
  • C89/C90 standard (ISO/IEC 9899:1990):
  • 4.6.2.1 The longjmp function

関連項目

コンテキストを保存します
(関数マクロ) [edit]