打印
[软件资料]

使用setjmp和longjmp函数处理异常

[复制链接]
378|6
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
LOVEEVER|  楼主 | 2024-4-7 22:52 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

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

int setjmp(jmp_buf env);
void longjmp(jmp_buf env, int val);

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

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

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

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

int main() {
    // 设置跳转点,并接收返回值
    int ret = setjmp(env);
    // 如果返回值为0,则表示正常执行
    if (ret == 0) {
        // 调用foo函数,传入一个非零值
        foo(10);
        // 调用foo函数,传入一个零值
        foo(0);
    } else {
        // 如果返回值不为0,则表示发生错误或异常,根据返回值打印出错信息
        switch (ret) {
            case 1:
                printf("Error: division by zero\n");
                break;
            default:
                printf("Unknown error\n");
                break;
        }
    }
    return 0;
}

输出:

100 / 10 = 10
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会直接跳转到错误处理或资源释放的代码,而不需要逐层返回

使用特权

评论回复
5
小小蚂蚁举千斤| | 2024-4-16 11:35 | 只看该作者
在发生错误或异常时,使用setjmp和longjmp会直接跳转到错误处理,更加快捷

使用特权

评论回复
6
OKAKAKO| | 2024-4-19 18:07 | 只看该作者
全局或静态存储期的变量对setjmp和longjmp影响还是比较大的

使用特权

评论回复
7
星辰大海不退缩| | 2024-4-21 12:42 | 只看该作者
val是一个用于传递跳转原因的整数值,它不能为0。setjmp函数用于设置跳转点,并返回0;longjmp函数用于跳转到跳转点,并使setjmp函数返回val

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

291

主题

1900

帖子

4

粉丝