setjmp 与 longjmp
setjmp和longjmp是C语言独有的,只有将它们结合起来使用,才能达到程序控制流有效转移的目的,按照程序员的预先设计的意图,去实现对程序中可能出现的异常进行集中处理。
先来看一下这两个函数的定义吧:
setjmp和longjmp的函数原型在setjmp.h中
函数原型:
int setjmp(jmp_buf envbuf);
setjmp函数用缓冲区envbuf保存系统堆栈的内容,以便后续的longjmp函数使用。setjmp函数初次启用时返回0值。
void longjmp(jmp_buf envbuf, int val);
longjmp函数中的参数envbuf是由setjmp函数所保存的堆栈环境,参数val设置setjmp函数的返回值。longjmp函数本身是没有返回值的,它执行后跳转到保存envbuf参数的setjmp函数调用,并由setjmp函数调用返回,此时setjmp函数的返回值就是val。
上面的说明有点拗口,通俗的解释是:先调用setjmp,用变量envbuf记录当前的位置,然后调用longjmp,返回envbuf所记录的位置,并使setjmp的返回值为val。当时用longjmp时,envbuf的内容被销毁了。其实这里的“位置”一词真正的含义是栈定指针。
接着让我们看一个小例子吧:
#include
#include
jmp_buf buf;
banana(){
printf("in banana() \n");
longjmp(buf,1);
printf("you'll never see this,because i longjmp'd");
}
main()
{
if(setjmp(buf))
printf("back in main\n");
else{
printf("first time through\n");
banana();
}
}
(代码段引自《C专家编程》:p)
这段代码的打印结果是:
first time through
in banana()
back in main
仔细看一下应该更能体会这对函数的作用了吧。
setjmp/longjmp的最大用处是错误恢复,类似try ...catch...
他们的功能比goto强多了,goto只能在函数体内跳来跳去,而setjmp/longjmp可以在到过的所有位置间。
从java、.net世界来的兄弟们也许会很不屑于这对函数,也许会觉得这样的功能会使代码的可读性变差。不过请别忘了,这里是C的世界,每个世界有每个世界的哲学,OO只是方法学的一种,而不是全部。quake3是用C写的,据看过其代码的前辈说,其模块化非常好,所以这也是我看quake3代码的初衷。(哦,算了吧,写游戏不是随便说说的...)
注:
我第一次看到setjmp是在quake3代码的Com_Init中,
/*
=================
Com_Init
=================
*/
void Com_Init( char *commandLine ) {
char *s;
Com_Printf( "%s %s %s\n", Q3_VERSION, CPUSTRING, __DATE__ );
if ( setjmp (abortframe) ) {
Sys_Error ("Error during initialization");
}
....
卡马克在这里也是当catch用的,其中的一句注释是这么写的:
jmp_buf abortframe; // an ERR_DROP occured, exit the entire frame
转载于:https://www.cnblogs.com/Huluwa-Vs-Aoteman/p/3439489.html
setjmp 与 longjmp相关推荐
- Linux学习之setjmp和longjmp函数
nsetjmp和longjmp函数实现函数之间的跳转(需包含头文件"setjmp.h"): 函数原型:int setjmp(jmp_buf env); void longjmp ...
- 递归和函数栈与setjmp和longjmp的关系
递归每执行一次都会释放一次函数栈 setjmp 记录函数栈的栈顶 longjmp 寻找函数栈的栈顶 如果longjmp找到了他要寻找的函数栈顶 调用setjmp的函数栈不会被释放 所以setjmp 和 ...
- setjmp()、longjmp() Linux Exception Handling/Error Handling、no-local goto
目录 1. 应用场景 2. Use Case Code Analysis 3. 和setjmp.longjmp有关的glibc and eglibc 2.5, 2.7, 2.13 - Buffer O ...
- C异常处理实现: setjmp和longjmp
此文为internet上选摘,过后我会用自己的理解补充此文. ------------ 将对setjmp与longjmp的具体使用方法和适用的场合,进行一个非常全面的阐述. 另外请特别注意,setjm ...
- 【转】浅析C语言的非局部跳转:setjmp和longjmp
转自 http://www.cnblogs.com/lienhua34/archive/2012/04/22/2464859.html C语言中有一个goto语句,其可以结合标号实现函数内部的任意跳转 ...
- 不同函数之间的跳转setjmp和longjmp
我们学过C语言中的goto,只能当前函数里面跳转是不能跨越函数的.setjmp和longjmp却可以跨越函数跳转. #include <stdio.h> #include <setj ...
- [转]全面了解setjmp与longjmp的使用
将对setjmp与longjmp的具体使用方法和适用的场合,进行一个非常全面的阐述. 另外请特别注意,setjmp函数与longjmp函数总是组合起来使用, ...
- C异常处理机制:setjmp和longjmp
setjmp()和longjum()是通过操纵过程活动记录实现的.它是C语言所独有的.它们部分你不了C语言有限的转移能力.这个两个函数协同工作,如下所示: *setjmp(jmp_buf j) ...
- 利用C语言中的setjmp和longjmp,来实现异常捕获和协程
一.前言 二.函数语法介绍 与 goto 语句比较 与 fork 函数比较 与 Python 语言中的 yield/resume 比较 三.利用 setjmp/longjmp 实现异常捕获 四.利用 ...
- linux C下的setjmp与longjmp介绍
setjmp和longjmp是C语言独有的,只有将它们结合起来使用,才能达到程序控制流有效转移的目的,按照程序员的预先设计的意图,去实现对程序中可能出现的异常进行集中处理. 先来看一下这两个函数的定义 ...
最新文章
- HDFS组件性能调优:数据平衡
- Spring(十八):Spring AOP(二):通知(前置、后置、返回、异常、环绕)
- golang select关键字用法
- 解决oracle ORA-01078,LRM-00109故障一例!
- 负载均衡沙龙活动第二期现场问答汇集
- 静态链接库、动态链接库和动态加载库
- C#中获取指定路径下指定后缀名的所有文件的路径的list
- etcd与mysql_etcd数据库备份与还原
- eclipse中项目内存溢出问题
- [BZOJ2761/Luogu4305][JLOI2011]不重复数字 题解
- .net @什么意思_.NET和F#周报2019-4 各地微软技术俱乐部汇总 ML.NET 0.10
- java如何进行性能调优,Java性能调优常用方法
- Unity3D中2D图片动画进行帧动画播放
- 电脑调节,电脑调节亮度怎么调
- 2017知乎看山杯总结(多标签文本分类)
- 009 Ubuntu安装Google浏览器
- Eclipse使用Log4j2的详细教程
- 维特智能单轴高精度旋转角度传感器航向倾角仪无漂移HWT101CT
- Allegro贴片元件封装制作
- GFP:新一代多业务传输技术(转)