3

C 参考手册的附录 B 描述了两个函数setjmplongjmp一个称为非本地跳转的东西。除了setjmp保存状态信息和 longjmp 恢复的基本了解之外state,我一直无法理解此功能的确切流程和用例。

那么,这个功能究竟完成了什么,它在哪里有用?

4

1 回答 1

6

至于控制流:setjmp返回两次,longjmp永不返回。当你setjmp第一次调用来存储环境时,它返回零,当你调用时,控制流通过参数中提供的值longjmp返回。setjmp

(请注意,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如果你想以几种不同的方式返回,你可以使用 a switch,但是:

    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 回答