3

C リファレンス マニュアルの付録 B では、2 つの関数setjmpと、非ローカル ジャンプlongjmpと呼ばれるものについて説明しています。状態情報を保存し、longjmp が を復元するという基本的な理解は別として、この機能の正確なフローと使用例を理解できていません。setjmpstate

では、この機能は正確には何を達成し、どこで役立つのでしょうか?

4

1 に答える 1

6

制御フローに関しては、setjmp2 回返され、longjmp決して返されません。setjmp環境を保存するために初めて呼び出すと、ゼロが返されます。 を呼び出すlongjmpと、制御フローは fromsetjmpに渡され、引数に指定された値が返されます。

(実際には関数である必要はないことに注意してくださいsetjmp。マクロであってもかまいませんlongjmp。しかし、は関数です。)

ユースケースは、一般に「エラー処理」および「これらの関数を使用しない」として引用されます。

制御フローの例を次に示します。

jmp_buf env;

void foo()
{
    longjmp(&env, 10);                      +---->----+
}                                           |         |
                                            |         |
int main()              (entry)---+         ^         V
{                                 |         |         |
    if(setjmp(&env) == 0)         | (= 0)   |         | (= 10)
    {                             |         ^         |
        foo();                    +---->----+         |
    }                                                 +---->----+
    else                                                        |
    {                                                           |
        return 0;                                               +--- (end)
    }
}

ノート:

  • に 0 を渡すことはできませんlongjmp。その場合、1によって返されsetjmpます。

  • setjmp対応する の前に呼び出した関数から戻ってはなりませんlongjmp。つまり、コール スタックのlongjmpでのみ呼び出す必要があります。 setjmp

  • (@wildplasser に感謝:)の結果を実際に保存setjmpすることはできません。switchただし、いくつかの異なる方法で戻りたい場合は、 a を使用できます。

    switch (setjmp(&env))
    {
    case 0:   // first call
    case 2:   // returned from longjmp(&env, 2)
    case 5:   // returned from longjmp(&env, 5)
    // etc.
    }
    
于 2013-05-19T15:27:40.180 に答える