C 标准库 - <setjmp.h>
setjmp.h 头文件定义了
- 宏 setjmp()
- 函数 longjmp()
- 变量类型 jmp_buf
jmp_buf 该变量类型会绕过正常的函数调用和返回规则。
jmp_buf 这是一个用于存储宏 setjmp() 和函数 longjmp() 相关信息的数组类型。
宏
int setjmp(jmp_buf environment);
这个宏把当前环境保存在变量 environment 中,以便函数 longjmp() 后续使用。
- 返回零:直接调用这个宏
- 返回非零:调用longjmp() 函数
库函数
void longjmp(jmp_buf environment, int value);
该函数恢复最近一次调用 setjmp() 宏时保存的环境,jmp_buf 参数的设置是由之前调用 setjmp() 生成的。
总结:当调用setjmp() 宏时会保存当前环境,用于将来跳转回此处。
实例代码一
#include <stdio.h>
#include <setjmp.h>
static jmp_buf buf;
void second(void) {
printf("second\n"); // 打印
longjmp(buf,0); // 跳回setjmp的调用处 - 使得setjmp返回值为1
}
void first(void) {
second();
printf("first\n"); // 不可能执行到此行
}
int main() {
if ( ! setjmp(buf) ) {
first(); // 进入此行前,setjmp返回0
} else { // 当longjmp跳转回,setjmp返回1,因此进入此行
printf("main\n"); // 打印
}
return 0;
}
输出:
second
main
longjump的第二个参数是影响(而不是被影响)setjmp的返回值的
#include <stdio.h>
#include <setjmp.h>
static jmp_buf buf;
int main(void)
{
int i;
printf("%d\n",i = setjmp(buf));//第一次输出0,第二次输出longjmp的第二个参数。
if (i==0)
longjmp(buf,3);//可自行修改第二参数查看不同结果。
return 0;
}
运行结果为:
0
3
但是当我没把第二个参数设置为0时该怎么输出
#include <stdio.h>
#include <setjmp.h>
static jmp_buf buf;
int main(void)
{
int i;
printf("%d\n",i = setjmp(buf));//第一次输出0,第二次输出longjmp的第二个参数。
if (i==0)
longjmp(buf,3);//可自行修改第二参数查看不同结果。
printf("after\n");
return 0;
}
输出:
0
1
after
实际上并没有产生我们认为的那种无限循环。
于是可以认为第二次返回后,不会执行以前执行过的代码。