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

1. 作用:

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

2. 函数原型:

#include 
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 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#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 






你可能感兴趣的:(linux应用程序设计)