setjmp和longjmp函数

来源:互联网 发布:地球下面是什么 知乎 编辑:程序博客网 时间:2024/05/10 23:32

    在C中,goto语句是不能跨越函数的,而执行这类跳转功能的是函数setjmp和longjmp。这两个函数对于处理发生在深层嵌套函数调用中的出错情况是非常有用的

#include <setjmp.h>

int setjmp(jmp_buf env);

返回值:若直接调用则返回0, 若从longjmp调用则返回非0值

void longjmp(jmp_buf env, int val);

在希望返回到的位置调用setjmp,setjmp参数env的类型是一个特殊类型jmp_buf。这一数据类型是某种形式的数组,其中存放在调用longjmp时能用来恢复栈状态的所有信息。因为需在另一个函数中引用env变量,所以规范的处理方式是将env变量定义为全局变量。

当检查到一个错误时,则以两个参数调用longjmp函数。第一个就是在调用setjmp时所用的env;第二个参数是具有非0值的val,它将成为从setjmp处返回的值。使用第二个参数的原因是对于一个setjmp可以有多个longjmp。例如,可以在函数f1中以val为1调用longjmp,也可在函数f2中以val为2调用longjmp。这样setjmp的返回值就会是1或2,通过测试返回值可判断造成返回的longjmp是在f1还是在f2中。

注意:

1)在信号处理程序中进行非局部转移时应当使用sigsetjmp和siglongjmp这两个函数。

#include <setjmp.h>

int sigsetjmp(sigjmp_buf env, int savemask);

返回值:若直接调用则返回0,若从siglongjmp调用返回则返回非0值

void siglongjmp(sigjmp_buf env, int val);

2)这两个函数与setjmp和longjmp之间的唯一区别是sigsetjmp增加了一个参数。如果savemask非0,则sigsetjmp在env中保存进程的当前信号屏蔽字。调用siglongjmp时,如果带非0 savemask的sigsetjmp调用已经保存了env,则siglongjmp从其中恢复保存的信号屏蔽字。

引用自UNIX环境高级编程

0 0