在setjmp.h中定义的C中的非本地跳转如何工作?
C参考手册 ,附录B描述了两个函数setjmp
和longjmp
用于称为非本地跳转 。 除了基本理解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. }