linux系统中的setjmp()和longjmp()函数

1. 作用:

setjmp()和longjmp() 可以实现非局部控制转移即从一个函数到另外一个函数的跳转。

2. 函数原型:

#include <setjmp.h>
int setjmp(jmp_buf env);
void longjmp(jmp_buf env);
setjmp函数设置返回点,保存调用函数的栈环境与env中(相当于保护现场)。

longjmp的作用使用setjmp保存在env中的栈环境信息返回到setjmp的位置,也就是当执行longjmp时程序又回到setjmp处(相当于恢复现场)。

setjmp有两个作用:

1)保存调用函数的栈环境于env中,返回值为0

2)作为longjmp的返回目标地,返回值为longjmp的第二个参数(当第个参数为0时返回值为1)

3. jmp_buf数据类型

typedef struct __jmp_buf_tag jmp_buf[1];
jmp_buf实际是一个数组,内存分配在栈空间中,作为参数传递时是一个指针(指向调用函数的栈帧)。

4. longjmp 返回时变量取值情况

全局变量(静态变量),其值为最后的定值。

自动变量,其值应当维持最后的定值不变但还取决于编译器的优化。

5. 具体实例

/*
 * main.c
 *
 *  Created on: 2016年10月10日
 *      Author: chy
 */
#include <sys/types.h>
#include <sys/unistd.h>
#include <sys/stat.h>
#include <setjmp.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#define ERR(t) { fprintf(stderr,t); exit(1)}

jmp_buf env;
int num1;

void test(int a,int b,int c)
{
	printf("test() %d %d %d\n",a,b,c);
	longjmp(env,1);
}

int main()
{
	volatile int num2;
	int num3;
	num1 = 1,num2 = 3, num3 = 4;
	printf("%d %d %d\n",num1,num2,num3);

	if(setjmp(env))
	{
		printf("jmp after data is: num1 = %d num2 = %d num3 = %d \n",num1,num2,num3);
		exit(0);
	}

	num1 = 2,num2 = 6, num3 = 8;
	test(num1, num2, num3);

	return 0;
}

gcc编译器不使用优化时:

chy@chy-Erazer-Z410:~/xueXi/obj/ecilpse/C/jmp/src$ gcc main.c -o jmp
chy@chy-Erazer-Z410:~/xueXi/obj/ecilpse/C/jmp/src$ ./jmp
1 3 4
test() 2 6 8
jmp after data is: num1 = 2 num2 = 6 num3 = 8 
使用-O2优化时:

chy@chy-Erazer-Z410:~/xueXi/obj/ecilpse/C/jmp/src$ gcc -O2 main.c -o jmp
chy@chy-Erazer-Z410:~/xueXi/obj/ecilpse/C/jmp/src$ ./jmp
1 3 4
test() 2 6 8
jmp after data is: num1 = 2 num2 = 6 num3 = 4 






  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值