C 参考手册的附录 B 描述了两个函数setjmp
和longjmp
一个称为非本地跳转的东西。除了setjmp
保存状态信息和 longjmp 恢复的基本了解之外state
,我一直无法理解此功能的确切流程和用例。
那么,这个功能究竟完成了什么,它在哪里有用?
至于控制流: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.
}