C ライブラリ関数 -longjmp()

C 标准库 - <setjmp.h>C 標準ライブラリ - <setjmp.h>

説明

C ライブラリ関数void longjmp(jmp_buf environment, int value)直近の呼び出しを復元setjmp()マクロ時に保存された環境、jmp_buf引数の設定は、以前の setjmp() 呼び出しによって生成されます。

longjmp()C 標準ライブラリ<setjmp.h>中の関数であり、非ローカルジャンプを実行するために使用されます。プログラムがスタックの複数のフレーム間でジャンプすることを可能にし、通常はエラー処理や例外処理、ならびに特定の状況での制御フローの変更に使用されます。

宣言

以下は longjmp() 関数の宣言です。

#include <setjmp.h>

void longjmp(jmp_buf env, int val);

引数

  • env:1つのjmp_buf型の変数で、保存しているsetjmp()の戻り情報。
  • val:1つの整数値として、setjmp()の戻り値。

戻り値

longjmp() 関数自体には戻り値はありませんが、プログラムの制御フローを以前に setjmp() を呼び出した位置にジャンプさせ、val を setjmp() の戻り値とします。

例

以下の例は、longjmp() 関数の使い方を示しています。

例

#include <stdio.h>
#include <setjmp.h>

static jmp_buf buf;

void second(void) {
    printf("second\n");         // 出力
    longjmp(buf,1);             // setjmp の呼び出し元にジャンプして戻る - setjmp の戻り値を1にする
}

void first(void) {
    second();
    printf("first\n");          // この行が実行されることはありません
}

int main() {  
    if ( ! setjmp(buf) ) {
        first();                // この行に入る前、setjmp は0を返す
    } else {                    // longjmp がジャンプして戻ると、setjmp は1を返すため、この行に入る
        printf("main\n");       // 出力
    }

    return 0;
}

上記のプログラムをコンパイルして実行してみましょう。これにより以下の結果が得られます:

second
main

注意事項

  • 使用するlongjmp()とsetjmp()には注意が必要です。なぜなら、それらはコードを理解しにくくし、デバッグを困難にする可能性があるからです。特に大規模なプログラムではそうです。
  • longjmp()通常のリソースクリーンアップやデストラクタ呼び出しをバイパスする可能性があり、その結果、リソースリークや未定義の動作を引き起こす可能性があります。
  • マルチスレッドやシグナルハンドラを扱う環境での使用は避けるべきです。longjmp()とsetjmp()。

使用シーン

  • エラー処理と例外処理:longjmp()とsetjmp()シンプルなエラー処理や例外処理のメカニズムを実装するために使用できます。
  • ステートマシン:ステートマシンの状態遷移では、異なる状態間でジャンプする必要がある場合があります、longjmp()とsetjmp()このような状態遷移を実装するために使用できます。
  • シグナル処理と併用する:いくつかの特殊な状況では、longjmp()とsetjmp()シグナルハンドラからジャンプして抜け出すために使用できます。

まとめ

longjmp()とsetjmp()非常に柔軟なメカニズムを提供し、プログラムの異なる部分間でジャンプすることができますが、潜在的な問題や未定義の動作を避けるために、それらを使用する際には細心の注意が必要です。それらは通常、エラー処理や例外処理、および特定の状況での制御フローの変更に使用されます。

C 标准库 - <setjmp.h>C 標準ライブラリ - <setjmp.h>

その他の拡張