博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
setjmp 与 longjmp
阅读量:5916 次
发布时间:2019-06-19

本文共 3099 字,大约阅读时间需要 10 分钟。

hot3.png

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。

jmp_buf 记录了栈、指令位置等信息:

1,如果有多个setjmp 使用同一个jmp_buf, 那么longjmp会跳转到最近的setjmp位置: 

#include "apue.h"#include 
static void f1(int, int, int, int);static void f2(void);static jmp_buf jmpbuffer;static int globval;intmain(void){ int autoval; register int regival; volatile int volaval; static int statval; globval = 1; autoval = 2; regival = 3; volaval = 4; statval = 5; if (setjmp(jmpbuffer) != 0) { printf("in main,after longjmp:\n"); printf("globval = %d, autoval = %d, regival = %d,"     " volaval = %d, statval = %d\n",     globval, autoval, regival, volaval, statval); exit(0); } /*  * Change variables after setjmp, but before longjmp.  */ globval = 95; autoval = 96; regival = 97; volaval = 98; statval = 99; f1(autoval, regival, volaval, statval); /* never returns */ exit(0);}static voidf1(int i, int j, int k, int l){ printf("in f1():\n"); printf("globval = %d, autoval = %d, regival = %d,"     " volaval = %d, statval = %d\n", globval, i, j, k, l);    if(setjmp(jmpbuffer) != 0){        printf("in f1, after longjmp!");        //longjmp(jmpbuffer,2);        exit(0);    }     f2();}static voidf2(void){    printf("in f2");    longjmp(jmpbuffer, 1);}

 

2, 下面的使用方式会形成死循环:

if( setjmp(jmpbuffer) != 0 ){    printf("in f1, after longjmp!");    longjmp(jmpbuffer,2);    exit(0);}

 

3, 如果想实现多个不同的跳转,可以使用多个jmp_buf :

#include "apue.h"#include 
static void f1(int, int, int, int);static void f2(void);static jmp_buf jmpbuffer;static jmp_buf jmpbuffer2;static int globval;intmain(void){ int autoval; register int regival; volatile int volaval; static int statval; globval = 1; autoval = 2; regival = 3; volaval = 4; statval = 5; if (setjmp(jmpbuffer2) == 2) { printf("\n in main,after longjmp:\n"); printf("globval = %d, autoval = %d, regival = %d,"     " volaval = %d, statval = %d\n",     globval, autoval, regival, volaval, statval); exit(0); } /*  * Change variables after setjmp, but before longjmp.  */ globval = 95; autoval = 96; regival = 97; volaval = 98; statval = 99; f1(autoval, regival, volaval, statval); /* never returns */ exit(0);}static voidf1(int i, int j, int k, int l){ printf("in f1():\n"); printf("globval = %d, autoval = %d, regival = %d,"     " volaval = %d, statval = %d\n", globval, i, j, k, l);    if(setjmp(jmpbuffer) != 0){        printf("in f1, after longjmp!\n");        longjmp(jmpbuffer2,2);        exit(0);    }     f2();}static voidf2(void){    printf("in f2\n"); longjmp(jmpbuffer, 1);}

 

相应的输出:

in f1():globval = 95, autoval = 96, regival = 97, volaval = 98, statval = 99in f2in f1, after longjmp! in main,after longjmp:globval = 95, autoval = 96, regival = 97, volaval = 98, statval = 99

 

 

转载于:https://my.oschina.net/u/255456/blog/388279

你可能感兴趣的文章
linux基础命令 rm
查看>>
「阿里面试系列」面试加分项,从jvm层面了解线程的启动和停止
查看>>
BigInteger实现原理
查看>>
下列说法正确的有:()
查看>>
栈帧 动态链接
查看>>
图像显示深入学习二:setContentView(...)过程分析
查看>>
vim介绍 颜色显示 一般模式下移动光标、复制、剪切、粘贴
查看>>
DR模式LVS搭建、keepalived+LVS
查看>>
CentOS6.5 安装ZooKeeper3.4.10
查看>>
企业级框架整合Springmvc+mybatis+restful+bootstrap
查看>>
SaaS加速器 III 技术中心:提供SaaS Launchkit,快速定制,一云多端等能力,一云多端将通过小程序云实现...
查看>>
iptables实例之nat表应用
查看>>
Kafka Producer Consumer
查看>>
JSP 语法
查看>>
表白程序?79行Python表白程序已发送,请接收,滴滴滴
查看>>
JS 获取浏览器和屏幕宽高信息
查看>>
visualvm监控tomcat
查看>>
虚拟机类加载机制(主动应用和被动引用)
查看>>
如何让ajaxfileupload.js支持IE9,IE10,并可以传递多个参数?
查看>>
VirtualBox 5 WIN10系统下切换到全屏设置方法:
查看>>