非本地跳转
非本地跳转(Non-local Jump)是C语言提供的一种异常控制流机制,允许程序从一个函数直接跳转到另一个函数中之前保存的执行点,跨越正常的函数调用返回链。
setjmp:setjmp(jmp_buf env) 保存当前的堆栈上下文(包括程序计数器、栈指针、通用寄存器等)到缓冲区 env 中。第一次直接调用时返回 0。被 longjmp 唤醒时”再次返回”,但此时返回的是 longjmp 传入的非零值。
longjmp:longjmp(jmp_buf env, int val) 从缓冲区 env 中恢复之前保存的寄存器状态,使程序计数器跳回到 setjmp 调用处。val 被作为 setjmp 的返回值。longjmp 不会返回——它直接跳转到目标位置。
调用一次,返回多次:setjmp 是一个特殊的函数——它被调用一次,但可能因多次 longjmp 调用而返回多次。每次 longjmp 都会使 setjmp 以不同返回值”再次返回”。
应用场景:
- 深层嵌套的错误恢复:在多层函数调用中发生错误时,不需要逐层返回,直接
longjmp到顶层的错误处理代码。 - 信号处理中的特殊控制流:信号处理程序中检测到致命错误时,
longjmp恢复到主程序的安全点。
限制:longjmp 只能跳转到尚未返回的 setjmp 所在函数(即调用栈上依然存在的函数),跳转到已返回的函数是未定义行为。