在setjmp.h中定义的C中的非本地跳转如何工作?

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

那么,这个function到底完成了什么,它在哪里有用?

至于控制流程: setjmp返回两次,而longjmp永远不会返回。 当你第一次调用setjmp时,为了存储环境,它返回零,当你调用longjmp ,控制流传setjmp返回参数中提供的值。

(注意, setjmp实际上不需要是函数;它可能是一个宏。但是, longjmp是一个函数。)

用例通常被称为“error handling”,“不使用这些function”。

这是一个小控制流示例:

 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 。 如果这样做,则setjmp返回1

  • 您不能从相应longjmp之前调用setjmp的函数返回。 换句话说, longjmp只能在调用堆栈中的setjmp 之上调用。

  • (感谢@wildplasser :)你实际上无法存储 setjmp的结果。 如果您想以多种不同的方式返回,可以使用switch

     switch (setjmp(&env)) { case 0: // first call case 2: // returned from longjmp(&env, 2) case 5: // returned from longjmp(&env, 5) // etc. }