C言語におけるsetjmpとlongjmpの実際的な使い方 質問する

C言語におけるsetjmpとlongjmpの実際的な使い方 質問する

setjmp()組み込みプログラミングで関数が実際にどこで使用できるかを正確に説明してくれる人はいますかlongjmp()? これらはエラー処理用であることは知っています。ただし、使用例をいくつか知りたいです。

ベストアンサー1

エラー処理
他の多くの関数にネストされた関数の奥深くにエラーがあり、エラー処理が最上位レベルの関数でのみ意味があるとします。

中間のすべての関数が正常に戻り、戻り値またはグローバル エラー変数を評価して、それ以上の処理が意味をなさないか、または悪いことになるかどうかを判断しなければならないとしたら、非常に面倒で扱いにくいものになるでしょう。

これは、setjmp/longjmp が意味を成す状況です。これらの状況は、他の言語 (C++、Java) の例外が意味を成す状況に似ています。

コルーチン
エラー処理の他に、C で setjmp/longjmp が必要になる別の状況も考えられます。

実装する必要がある場合は、コルーチン

ここにちょっとしたデモの例があります。これが Sivaprasad Palas からのサンプル コードのリクエストを満たし、setjmp/longjmp がコルーチンの実装をどのようにサポートするかという TheBlastOne の質問 (非標準の動作や新しい動作に基づいていないように見える) に答えてくれることを願っています。

編集:
それは実際には未定義の動作を行うlongjmp コールスタック (MikeMB のコメントを参照してください。ただし、まだ確認する機会がありません)。

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

jmp_buf bufferA, bufferB;

void routineB(); // forward declaration 

void routineA()
{
    int r ;

    printf("- 12 : (A1)\n");

    r = setjmp(bufferA);
    if (r == 0) routineB();

    printf("- 17 : (A2) r=%d\n",r);

    r = setjmp(bufferA);
    if (r == 0) longjmp(bufferB, 20001);

    printf("- 22 : (A3) r=%d\n",r);

    r = setjmp(bufferA);
    if (r == 0) longjmp(bufferB, 20002);

    printf("- 27 : (A4) r=%d\n",r);
}

void routineB()
{
    int r;

    printf("- 34 : (B1)\n");

    r = setjmp(bufferB);
    if (r == 0) longjmp(bufferA, 10001);

    printf("- 39 : (B2) r=%d\n", r);

    r = setjmp(bufferB);
    if (r == 0) longjmp(bufferA, 10002);

    printf("- 44 : (B3) r=%d\n", r);

    r = setjmp(bufferB);
    if (r == 0) longjmp(bufferA, 10003);
}


int main(int argc, char **argv) 
{
    routineA();
    return 0;
}

出力

- 12 : (A1)
- 34 : (B1)
- 17 : (A2) r=10001
- 39 : (B2) r=20001
- 22 : (A3) r=10002
- 44 : (B3) r=20002
- 27 : (A4) r=10003

次の図は実行フローを示しています。
実行の流れ

警告メモ

setjmp/longjmp を使用する場合は、考慮されないことが多いローカル変数の有効性に影響を与えることに注意してください。このトピックに関する質問

おすすめ記事