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相关推荐

  1. Linux学习之setjmp和longjmp函数

    nsetjmp和longjmp函数实现函数之间的跳转(需包含头文件"setjmp.h"): 函数原型:int setjmp(jmp_buf env);   void longjmp ...

  2. 递归和函数栈与setjmp和longjmp的关系

    递归每执行一次都会释放一次函数栈 setjmp 记录函数栈的栈顶 longjmp 寻找函数栈的栈顶 如果longjmp找到了他要寻找的函数栈顶 调用setjmp的函数栈不会被释放 所以setjmp 和 ...

  3. 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 ...

  4. C异常处理实现: setjmp和longjmp

    此文为internet上选摘,过后我会用自己的理解补充此文. ------------ 将对setjmp与longjmp的具体使用方法和适用的场合,进行一个非常全面的阐述. 另外请特别注意,setjm ...

  5. 【转】浅析C语言的非局部跳转:setjmp和longjmp

    转自 http://www.cnblogs.com/lienhua34/archive/2012/04/22/2464859.html C语言中有一个goto语句,其可以结合标号实现函数内部的任意跳转 ...

  6. 不同函数之间的跳转setjmp和longjmp

    我们学过C语言中的goto,只能当前函数里面跳转是不能跨越函数的.setjmp和longjmp却可以跨越函数跳转. #include <stdio.h> #include <setj ...

  7. [转]全面了解setjmp与longjmp的使用

                          将对setjmp与longjmp的具体使用方法和适用的场合,进行一个非常全面的阐述. 另外请特别注意,setjmp函数与longjmp函数总是组合起来使用, ...

  8. C异常处理机制:setjmp和longjmp

    setjmp()和longjum()是通过操纵过程活动记录实现的.它是C语言所独有的.它们部分你不了C语言有限的转移能力.这个两个函数协同工作,如下所示:     *setjmp(jmp_buf j) ...

  9. 利用C语言中的setjmp和longjmp,来实现异常捕获和协程

    一.前言 二.函数语法介绍 与 goto 语句比较 与 fork 函数比较 与 Python 语言中的 yield/resume 比较 三.利用 setjmp/longjmp 实现异常捕获 四.利用 ...

  10. linux C下的setjmp与longjmp介绍

    setjmp和longjmp是C语言独有的,只有将它们结合起来使用,才能达到程序控制流有效转移的目的,按照程序员的预先设计的意图,去实现对程序中可能出现的异常进行集中处理. 先来看一下这两个函数的定义 ...

最新文章

  1. HDFS组件性能调优:数据平衡
  2. Spring(十八):Spring AOP(二):通知(前置、后置、返回、异常、环绕)
  3. golang select关键字用法
  4. 解决oracle ORA-01078,LRM-00109故障一例!
  5. 负载均衡沙龙活动第二期现场问答汇集
  6. 静态链接库、动态链接库和动态加载库
  7. C#中获取指定路径下指定后缀名的所有文件的路径的list
  8. etcd与mysql_etcd数据库备份与还原
  9. eclipse中项目内存溢出问题
  10. [BZOJ2761/Luogu4305][JLOI2011]不重复数字 题解
  11. .net @什么意思_.NET和F#周报2019-4 各地微软技术俱乐部汇总 ML.NET 0.10
  12. java如何进行性能调优,Java性能调优常用方法
  13. Unity3D中2D图片动画进行帧动画播放
  14. 电脑调节,电脑调节亮度怎么调
  15. 2017知乎看山杯总结(多标签文本分类)
  16. 009 Ubuntu安装Google浏览器
  17. Eclipse使用Log4j2的详细教程
  18. 维特智能单轴高精度旋转角度传感器航向倾角仪无漂移HWT101CT
  19. Allegro贴片元件封装制作
  20. GFP:新一代多业务传输技术(转)

热门文章

  1. c++学习笔记(16) 递归
  2. three.js mtl材质贴图未显示_C4D材质到底该怎么用?大多数设计师都没搞明白!
  3. 国庆快乐,送3本Python书
  4. ubuntu无法打开外接硬盘
  5. tensorflow has no attribute logging
  6. DFINITY创始人:目前仍以Q1路线图为主要目标,正在进行创世启动前的安全审计
  7. SAP License:对煤化工行业的几点思考
  8. 迷宫的最短路径(bfs)
  9. vue.js慢速入门(1)
  10. 字符串之String类