setjmp与longjmp是属于C语言中的,当然,C++也会有这两个函数了。他们的原型如下:

int setjmp( jmp_buf env );

作用:第一次调佣时,将寄存器的当前状态信息全部存入到env中,并返回0。如果在某处调用了longjmp(env,x),且x!=0,则setjmp的返回值将设为x。而若x==0,则setjmp返回1

void longjmp( jmp_buf env,int value );

作用:重新存储当前寄存器的状态信息,并将setjmp的返回值设为value。

  简单概括之,如果你有月光宝盒,那么需要将月光宝盒在某处定一个时间点,比如2015年11月11日11点11分,后来,我在2016年感觉不爽,就直接使用月光宝盒回到2015年11月11日11点11分,当时所有的东西仍然没有变化,仅仅只有我知道我穿越了。那么setjmp就是用于设置时间点,会将必须的东西记录下来,保存在一个jmp_buf类型的变量中,此后,如果有longjmp想回到这个时间点,就可以直接跳回去。值得注意的是,这样不就一直在无限循环吗?当然还是有变化的,第一次调用setjmp时,返回的是0。当调用longjmp跳回去时,setjmp的返回值变成了非0值,这样就可以区分开来了。

  下面是个例子:

 void test()
{
jmp_buf jb;
int ret=setjmp(jb); //设置返回点,返回0.
if(ret!=) cout<<""<<endl; //这仅被输出1次。
if(ret==) longjmp(jb,);//回到jb处,并将ret设为非零。
}

  

  那么setjmp与longjmp在C++中的适用范围是什么?setjmp与longjmp如果跳出了当前函数的话,当前函数中声明的对象可是不会被析构的(不会调用析构函数),那么就存在了一定的危险,比如对象里还有动态申请的内存怎么办,然而C中就不存在这个问题了。并不是说不能用,只是必须了解它的利弊,才能更好地使用他。

  例子:

 class Rainbow
{
public:
Rainbow() {cout<<"Rainbow()"<<endl;}
~Rainbow() {cout<<"~Rainbow()"<<endl;}
};
jmp_buf jmpBuf;
void Summer()
{
Rainbow rb;
for(int i=;i>;--i)
cout<<"Happy Chinese Valentine's Day!"<<endl;
longjmp(jmpBuf,); //下面这句被忽略
cout<<"Oh no.I am being ignore."<<endl;
} int main()
{
test();
if(!setjmp(jmpBuf))
{
cout<<"setjmp() return a zero value!"<<endl;
Summer();
}
else
{
cout<<"setjmp() get a non-zero value!"<<endl;
}
return ;
}

  经测试,G++下并不会调用该析构函数。当然,你需要考虑编译器的智能程度,可能帮你做优化了。

  这种方法看起来与goto相似,但是是有区别的,区别如下:

  (1)goto语句不能跳出C语言当前的函数。

  (2)用longjmp只能跳回曾经到过的地方。在执行setjmp的地方仍留有一个过程活动记录。从这个角度上讲,longjmp更象是“从何处来”,而不是“要往哪去”。另外,longjmp接受一个额外的整形参数并返回它的值,这可以知道是由longjmp转移到这里的还是从上一条语句执行后自然执行到这里的。

  参考:http://blog.csdn.net/cscmaker/article/details/7584433

  

C中的setjmp与longjmp的更多相关文章

  1. setjmp()和longjmp()函数

    之前我们讲到了过程活动记录(AR),那么如何来操纵AR呢,一个可能的方法是,根据局部变量的地址进行推算,例如对于上面的a函数,执行a函数时的当前AR地址就是参数i的地址偏移8个字节,也就是 ((cha ...

  2. C 语言中 setjmp 和 longjmp

    在 C 语言中,我们不能使用 goto 语句来跳转到另一个函数中的某个 label 处:但提供了两个函数——setjmp 和 longjmp来完成这种类型的分支跳转.后面我们会看到这两个函数在处理异常 ...

  3. 非本地跳转之setjmp与longjmp

    非本地跳转(unlocal jump)是与本地跳转相对应的一个概念. 本地跳转主要指的是类似于goto语句的一系列应用,当设置了标志之后,可以跳到所在函数内部的标号上.然而,本地跳转不能将控制权转移到 ...

  4. setjmp()、longjmp() Linux Exception Handling/Error Handling、no-local goto

    目录 . 应用场景 . Use Case Code Analysis . 和setjmp.longjmp有关的glibc and eglibc 2.5, 2.7, 2.13 - Buffer Over ...

  5. setjmp 与 longjmp

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

  6. setjmp和longjmp的使用

    问题描述:          setjmp和longjmp的使用 问题解决:       setjmp和longjmp是C语言独有的,只有将它们结合起来使用,才能达到程序控制流有效转移的目的,按照程序 ...

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

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

  8. 【转载】setjmp和longjmp函数使用详解

    [说明]本文上半部分转载自 wykwdy007 的转载文章 http://blog.csdn.net/wykwdy007/article/details/6535322 --------------- ...

  9. 进程环境之setjmp和longjmp函数

    在C中,goto语句是不能跨越函数的,而执行这样跳转功能的是函数setjmp和longjmp.这两个函数对于处理发生在深层嵌套函数调用中的出错情况是非常有用的. setjmp和longjmp函数也称为 ...

随机推荐

  1. Jquery select 选中项中自定义的值

    给select 赋值,除了已有的value及text,新建一属性simple_name function GetDicOfficeList(dicType, sid) { $.ajax({ url: ...

  2. 使用Vibrator控制手机振动

    import android.os.Bundle;import android.os.Vibrator;import android.app.Activity;import android.app.S ...

  3. 电Call记录统计查询sql

    DECLARE @startTime datetimeset @startTime='2016-07-12' SELECT * FROM (--坐席号/电话个数/通话总时长select zuoxi a ...

  4. 浅谈C++源码的过国内杀软的免杀

    以下只是简单的思路和定位.也许有人秒过,但是不要笑话我写的笨方法.定位永远是过期不了的. 其实这里废话一下 , 本人并不是大牛 ,今天跟大家分享下 .所以写出这篇文章.(大牛飘过) 只是个人实战的经验 ...

  5. 记一个有想法却没能力实现的硬件产品——mp3校时闹钟

    枕头旁的闹钟,我想大家都用过,很便宜.用一节干电池供电.但其最大的缺点就是不太准,不能校时. 电池啥事用光,也不知道.钟是走的很慢,没按时闹,搞的自己迟了到. 于是就有了我的漫长思考过程... 先说手 ...

  6. ByteArray

    ByteArray:属性endian:String == Endian.BIG_ENDIAN/Endian.LITTLE_ENDIAN.length:uint ByteArray的字节数positio ...

  7. 常用控件产品官方文档/手册/API列表 c#控件文档API列表 asp.net控件产品技术文档中文版

    .netCHARTING报表图表控件 文档帮助手册Ab3d.PowerToys 文档帮助手册Ab3d.Reader3ds 文档帮助手册ABViewer 文档帮助手册 (工程图纸文档管理系统)Activ ...

  8. 100个iOS开发/设计面试题汇总

    常见问题 你昨天/这周学习了什么? 你为什么热衷于软件开发? 你对哪一种控制系统比较熟悉? 是否参与过GitHub项目? 是否参与过GitHub或其他同类型网站的iOS开源项目? 请描述一下你的iOS ...

  9. Windows Azure 实操 —— 迁移本地SharePoint服务器到Azure

    博客地址 http://blog.csdn.net/foxdave 注意:如果你是第二代虚拟机,那就别看这个了,老老实实在Azure上重新创建吧,Azure不支持第二代虚拟机. 写在之前,对Azure ...

  10. 一、XML语法

    xml声明xml指令:<? ?>xml编码与乱码xml元素(标签)CDATA区空格与换行会被认为是标签的内容xml-stylesheet指令解析xml内容 <?xml version ...