C语言异常控制:setjmp与longjmp详解

山海之间
山海之间
发布时间:2026-10-14 | 4人浏览过
原创

C语言的setjmp与longjmp是独特的控制流机制,允许程序在运行时跳转到之前保存的位置,通常用于集中处理程序中可能出现的深层错误或异常。

核心概念与定义

这两个函数的声明位于头文件 setjmp.h 中。它们的组合使用旨在按照预先设计的意图,实现对异常的集中处理。

第1步:定义缓冲区与环境保存

目的:创建一个环境缓冲区,并记录当前程序的执行状态(主要是栈指针)。

入口:调用 setjmp 函数。

动作:传入一个类型为 jmp_buf 的缓冲区变量,系统会将当前的堆栈内容保存到该变量中。

复制代码 代码如下:
int setjmp(jmp_buf envbuf);
  • 参数:envbuf 用于保存堆栈上下文的环境变量。
  • 返回值:当首次调用时,setjmp 返回 0。

第2步:触发跳转并恢复环境

目的:在非正常路径或发生错误时,跳回之前由 setjmp 保存的位置。

入口:调用 longjmp 函数。

动作:传入先前保存的 envbuf 和期望的返回值。

复制代码 代码如下:
void longjmp(jmp_buf envbuf, int val);
  • 参数:envbuf 是由 setjmp 保存的堆栈环境;val 将作为 setjmp 再次调用时的返回值。
  • 执行效果:longjmp 本身无返回值,它结束当前函数调用链,直接跳转到 setjmp 的位置。此时,setjmp 不再返回 0,而是返回 val。同时,envbuf 中的状态被销毁,不可重复用于跳转。

代码示例与执行流程

以下示例展示了 setjmp 和 longjmp 如何跨函数跳转:

复制代码 代码如下:
#include <stdio.h>
#include <setjmp.h>

jmp_buf buf;

void banana() {
    printf("in banana()\n");
    longjmp(buf, 1); // 触发跳转
    
    // 这行代码永远不会被执行
    printf("you'll never see this, because i longjmp'd");
}

int main() {
    if (setjmp(buf)) { // 第一次返回0,第二次返回1
        printf("back in main\n");
    } else {
        printf("first time through\n");
        banana(); // 进入子函数
    }
    return 0;
}

执行结果:

  • first time through
  • in banana()
  • back in main

主要应用场景

错误恢复: setjmp/longjmp 的最大用途是实现类似其他语言中 try...catch 的异常处理机制,允许程序从深层嵌套的错误中“抛出”到顶层进行统一处理。

范围优势: 相比于 goto 只能在当前函数内部跳转,setjmp/longjmp 可以在整个函数调用链的任何位置间进行跳转,实现了真正的非局部跳转。

以上就是C语言中setjmp与longjmp函数的详细内容,更多关于C语言异常处理的资料请关注本站其它相关文章!

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表