[软件资料] 使用setjmp和longjmp函数处理异常

[复制链接]
775|6
 楼主| LOVEEVER 发表于 2024-4-7 22:52 | 显示全部楼层 |阅读模式

使用setjmp和longjmp函数:这是一种用于实现非局部跳转的方法,就是在程序中设置一个跳转点,并在某些情况下跳转到该跳转点,从而绕过中间的一些代码或函数。这样可以在某些情况下模拟异常处理的效果,例如在发生错误或异常时,直接跳转到错误处理或资源释放的代码,而不需要逐层返回。setjmp和longjmp函数定义在setjmp.h头文件中,其语法为:

  1. int setjmp(jmp_buf env);
  2. void longjmp(jmp_buf env, int val);

其中env是一个用于存储跳转点信息的数据类型,它实际上是一个数组,包含了程序计数器、栈指针、寄存器等信息。val是一个用于传递跳转原因的整数值,它不能为0。setjmp函数用于设置跳转点,并返回0;longjmp函数用于跳转到跳转点,并使setjmp函数返回val。例如:

  1. #include <stdio.h>
  2. #include <setjmp.h>

  3. // 定义一个全局的env变量
  4. jmp_buf env;

  5. // 定义一个可能发生错误的函数
  6. void foo(int x) {
  7.     // 如果x为0,则发生除零错误,跳转到env,并传递1
  8.     if (x == 0) {
  9.         longjmp(env, 1);
  10.     }
  11.     // 否则,正常执行,并打印结果
  12.     printf("100 / %d = %d\n", x, 100 / x);
  13. }

  14. int main() {
  15.     // 设置跳转点,并接收返回值
  16.     int ret = setjmp(env);
  17.     // 如果返回值为0,则表示正常执行
  18.     if (ret == 0) {
  19.         // 调用foo函数,传入一个非零值
  20.         foo(10);
  21.         // 调用foo函数,传入一个零值
  22.         foo(0);
  23.     } else {
  24.         // 如果返回值不为0,则表示发生错误或异常,根据返回值打印出错信息
  25.         switch (ret) {
  26.             case 1:
  27.                 printf("Error: division by zero\n");
  28.                 break;
  29.             default:
  30.                 printf("Unknown error\n");
  31.                 break;
  32.         }
  33.     }
  34.     return 0;
  35. }

输出:

  1. 100 / 10 = 10
  2. Error: division by zero

可以看到,当调用foo函数时,如果传入的参数为0,则会触发longjmp函数,从而跳转到setjmp函数所在的位置,并使setjmp函数返回1。这样就可以根据返回值来判断发生了什么错误或异常,并进行相应的处理。
需要注意的是,使用setjmp和longjmp函数时要遵循一些规则和限制,例如:

1、不要在setjmp和longjmp之间修改env变量的内容。

2、不要在setjmp和longjmp之间修改任何具有全局或静态存储期的变量。

3、不要在setjmp和longjmp之间调用任何可能改变程序状态或资源的函数。

4、不要在多线程环境中使用setjmp和longjmp函数。
中国龙芯CDX 发表于 2024-4-10 11:16 | 显示全部楼层
setjmp函数用于设置跳转点,并返回0;longjmp函数用于跳转到跳转点,并使setjmp函数返回val
小夏天的大西瓜 发表于 2024-4-10 13:11 | 显示全部楼层
不要在setjmp和longjmp之间修改任何具有全局或静态存储期的变量。
szt1993 发表于 2024-4-11 08:00 | 显示全部楼层
在发生错误或异常时,使用setjmp和longjmp会直接跳转到错误处理或资源释放的代码,而不需要逐层返回
小小蚂蚁举千斤 发表于 2024-4-16 11:35 | 显示全部楼层
在发生错误或异常时,使用setjmp和longjmp会直接跳转到错误处理,更加快捷
OKAKAKO 发表于 2024-4-19 18:07 | 显示全部楼层
全局或静态存储期的变量对setjmp和longjmp影响还是比较大的
星辰大海不退缩 发表于 2024-4-21 12:42 | 显示全部楼层
val是一个用于传递跳转原因的整数值,它不能为0。setjmp函数用于设置跳转点,并返回0;longjmp函数用于跳转到跳转点,并使setjmp函数返回val
您需要登录后才可以回帖 登录 | 注册

本版积分规则

350

主题

2689

帖子

7

粉丝
快速回复 在线客服 返回列表 返回顶部