C参考手册,附录B描述了一些名为非本地跳转的函数setjmp
和longjmp
。除了setjmp
保存状态信息和longjmp恢复state
的基本理解之外,我还无法理解此功能的确切流程和用例。
那么,这个功能究竟完成了什么以及它在哪里有用?
答案 0 :(得分: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
的结果。如果您想以多种不同的方式返回,可以使用switch
,但是:
switch (setjmp(&env))
{
case 0: // first call
case 2: // returned from longjmp(&env, 2)
case 5: // returned from longjmp(&env, 5)
// etc.
}