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. 重点关注之自定义序列化方式(Protobuf和Msgpack)

    除了默认的JSON和XML序列化器外,如果想使用其它格式的(比如二进制)序列化器,也是可以的.比如著名的Protobuf和Msgpack,它们都是二进制的序列化器,特点是速度快,体积小.使用方法如下. ...

  2. 转载:完全卸载oracle11g步骤

    完全卸载oracle11g步骤: 1. 开始->设置->控制面板->管理工具->服务 停止所有Oracle服务. 2. 开始->程序->Oracle - OraHo ...

  3. js 数组去除空值

    for(var i = 0 ;i<wordarr.length;i++)                {                    if(wordarr[i] == "& ...

  4. POJ 1979 Red and Black dfs 难度:0

    http://poj.org/problem?id=1979 #include <cstdio> #include <cstring> using namespace std; ...

  5. Elasticsearch内存分配设置详解

    Elasticsearch默认安装后设置的内存是1GB,对于任何一个现实业务来说,这个设置都太小了.如果你正在使用这个默认堆内存配置,你的集群配置可能会很快发生问题. 这里有两种方式修改Elastic ...

  6. java.io中流的操作:字节流、字符流

    java.io中流的操作:字节流.字符流(1)使用File类打开一个文件(2)通过字节流或字符流的子类指定输出的位置(3)进行读/写操作(4)关闭输入/输出 1.字节流:主要是byte类型数据,以by ...

  7. Flexbox

    使用 Flexbox 的牛逼布局 .container { display: -webkit-flex; display: flex; } .initial { -webkit-flex: initi ...

  8. CodeForces 468A Program F

    Description Little X used to play a card game called "24 Game", but recently he has found ...

  9. fragment 添加menu

    http://bbs.51cto.com/thread-1091458-1-1.html 有详解 @Override public void onCreate(Bundle savedInstance ...

  10. Volatile vs VolatileRead/Write?

    You should never use Thread.VolatileRead/Write(). It was a design mistake in .NET 1.1, it uses a ful ...