setjmp和longjmp的"非本地跳转"
来源:互联网 发布:大数据为什么在贵阳 编辑:程序博客网 时间:2024/04/30 22:47
C语言中要实现"非本地跳转",C标准函数库提供了2个函数setjmp和longjmp来实现这个功能。头文件在<setjmp.h>。setjmp/longjmp的典型用途是例外处理机制的实现:利用longjmp恢复程序或线程的状态,甚至可以跳过栈中多层的函数调用。
函数声明:
SYNOPSIS #include <setjmp.h> int setjmp(jmp_buf env);DESCRIPTION A call to setjmp() shall save the calling environment in its env argument for later use by longjmp().
作用:建立本地的
jmp_buf
缓冲区并且初始化,用于将来跳转回此处。这个子程序[1] 保存程序的调用环境于env
参数所指的缓冲区,env
将被longjmp
使用。如果是从setjmp
直接调用返回,setjmp
返回值为0。如果是从longjmp
恢复的程序调用环境返回,setjmp
返回非零值。SYNOPSIS #include <setjmp.h> void longjmp(jmp_buf env, int val);DESCRIPTION The longjmp() function shall restore the environment saved by the most recent invocation of setjmp() in the same thread, with the corresponding jmp_buf argument. If there is no such invocation, or if the function containing the invocation of setjmp() has ter- minated execution in the interim, or if the invocation of setjmp() was within the scope of an identifier with variably modified type and execution has left that scope in the interim, the behavior is undefined. It is unspecified whether longjmp() restores the signal mask, leaves the signal mask unchanged, or restores it to its value at the time setjmp() was called.
作用:恢复
env
所指的缓冲区中的程序调用环境上下文,env
所指缓冲区的内容是由setjmp
子程序[1]调用所保存。value
的值从longjmp
传递给setjmp
。longjmp
完成后,程序从对应的setjmp
调用处继续执行,如同setjmp
调用刚刚完成。如果value
传递给longjmp
零值,setjmp
的返回值为1;否则,setjmp
的返回值为value
。示例1:
#include <stdio.h>#include <stdlib.h>#include <setjmp.h>static jmp_buf buf;intmain(void){ volatile int b; b = 3; if (setjmp(buf) != 0) //第一次调用返回0 { printf("%d\n", b); exit(0); } b = 5; longjmp(buf, 1); //val为1时返回setjmp的跳转 return 0;}
运行结果:
5
示例2:
#include <setjmp.h>#include "apue.h"static void f1(int, int, int);static void f2(void);static jmp_buf jmpbuffer;intmain(void){ int count; register int val; volatile int sum; count = 2; val = 3; sum = 4; if (setjmp(jmpbuffer) != 0) { printf("after longjmp: count = %d, val = %d, sum = %d\n", count, val, sum); exit(0); } count = 97; val = 98; sum = 99; f1(count, val, sum); return 0;}static void f1(int i, int j, int k){ printf("in f1(): count = %d, val = %d, sum = %d\n", i, j, k); f2();}static void f2(void){ longjmp(jmpbuffer, 1);}
如果不使用优化选项编译时
[root@localhost src]# gcc -Wall -I../include fig7_5.c error.c -o fig7_5[root@localhost src]# ./fig7_5 in f1(): count = 97, val = 98, sum = 99after longjmp: count = 97, val = 98, sum = 99
如果使用了优化选项后
[root@localhost src]# gcc -Wall -O -I../include fig7_5.c error.c -o fig7_5[root@localhost src]# ./fig7_5in f1(): count = 97, val = 98, sum = 99after longjmp: count = 2, val = 3, sum = 99从以上可以看出,易失变量(sum )不受优化的影响,在longjmp之后的值,是它在调用f1时的值。在我们所使用的setjmp(3)手册页上说明存放在存储器中的变量将具有longjmp时的值,而在CPU和浮点寄存器中的变量则恢复为调用setjmp时的值。这确实就是在运行程序7-5时所观察到的值。不进行优化时,所有这三个变量都存放在存储器中(亦即对val的寄存器存储类被忽略)。而进行优化时,count和val都存放在寄存器中(即使count并末说明为register) ,volatile变量则仍存放在存储器中。通过这一例子要理解的是,如果要编写一个使用非局部跳转的可移植程序,则必须使用volatile属性。
- setjmp和longjmp的"非本地跳转"
- setjmp和longjmp的"非本地跳转"
- setjmp()和longjmp()--c的非本地跳转
- 非本地跳转--setjmp(3C)和longjmp(3C
- 浅析C语言的非局部跳转:setjmp和longjmp
- C语言的非局部跳转:setjmp和longjmp
- 浅析C语言的非局部跳转:setjmp和longjmp
- 浅析C语言的非局部跳转:setjmp和longjmp
- 浅析C语言的非局部跳转:setjmp和longjmp
- 非局部跳转函数 setjmp 和 longjmp
- 非局部跳转函数 setjmp 和 longjmp .
- 【setjmp和longjmp 】 C语言的非局部跳转:setjmp和longjmp(跨函数长跳转)
- 非本地跳转函数setjmp,longjmp, sigsetjmp, siglongjmp
- csapp读书笔记-使用setjmp/sigsetjmp和longjmp/siglongjmp进行非本地跳转
- setjmp longjmp 非局部跳转
- setjmp与longjmp相结合,实现程序的非本地的跳转
- 使用setjmp()和longjmp()执行非局部跳转
- 非局部跳转语句---setjmp和longjmp函数
- C语言优先级
- 扩展金山提示框,使之带颜色
- ubuntu之scim输入法的安装
- sitemesh 项目中的使用
- ORACLE SQL Loader的详细语法
- setjmp和longjmp的"非本地跳转"
- 记录一些好文章.
- wpf app.config 客户端进行配置和修改.
- j2me图片转换为二进制的解决办法?
- 深刻理解Linux进程间通信(IPC)
- RAC架构之业务分割
- delphi 中实现当期日期 减去 若干小时的方法
- spring中的Bean配置注意的地方
- Solaris quota命令