在C中有时我们会使用goto语句用于运行跳转,可是不能跨越函数

#include <stdio.h>

void func2()
{
int num = 0;
dst2:
if (num > 0)
{
printf("func1()\n");
func3();
}
if (num == 1)
return;
num++;
goto dst2;
} void func3()
{
} void func1()
{
dst1:
func2();
goto dst2;//error
} int main()
{
func1();
return 0;
}

而在深层嵌套函数中的跳转,能够使用setjmp和longjmp函数。

这两个函数对于处理发生在深层嵌套函数中出错的情况是很实用的。

函数原型:

#include <setjmp.h>
int setjmp(jmp_buf env);
返回值:若直接调用则返回0,若从longjmp调用返回则返回非0值
void longjmp(jmp_buf env, int val);

參数说明:

setjmp的env參数的类型是一个特殊类型jmp_buf,这一数据类型是某种形式的数组,当中存放存放在调用longjmp时能用来恢复栈状态的全部信息

longjmp的env參数指定恢复栈到某个状态,val为非0值,使用第二个參数的原因是对于一个setjmp能够有多个longjmp。比如。在func2()中以val为2调用longjmp,

func3()以val3调用longjmp,调用longjmp导致程序跳转到对应的指定env处的setjmp.并导致setjmp返回val值。通过測试返回值可推断造成返回的longjmp是在func2()中还是func3()中

实例:

#include <stdio.h>
#include <setjmp.h> jmp_buf jmpbuffer;
int times = 0; void func3()
{
times++;
longjmp(jmpbuffer, 3);
} void func2()
{
func3();
} void func1()
{
int r;
r = setjmp(jmpbuffer);
printf("%d\n", r);
if (times == 1)
return;
func2();
} int main()
{
func1();
return 0;
}

longjmp跳转对变量的影响

longjmp实际上恢复栈的状态。所以我们能够猜測,对于全局变量和静态变量。不存储在栈区中,所以值不会受影响,而大多数实现不会回滚自己主动变量的值

若不希望自己主动变量的值被回滚,能够指定其具有volatile属性。

很多其它关于volatile见  http://blog.csdn.net/aspnet_lyc/article/details/17231989

实例:

#include <stdio.h>
#include <setjmp.h>
#include <stdlib.h> jmp_buf jmpbuffer; void func1()
{
int auto_data = 0;
static int static_data = 0;
volatile int volatile_data = 0; if (setjmp(jmpbuffer) != 0)
{
printf("after jmp:\n");
printf("auto: %d\n", auto_data);
printf("static: %d\n", static_data);
printf("volatile: %d\n", volatile_data);
exit(0);
}
printf("auto: %d\n", auto_data);
printf("static: %d\n", static_data);
printf("volatile: %d\n", volatile_data); auto_data++;
static_data++;
volatile_data++;
longjmp(jmpbuffer, 3);
} int main()
{
func1();
return 0;
}

以不带优化和带优化选项对此程序部分进行编译,运行结果:

不带优化编译gcc

带优化编译 gcc -O

存放在存储器中的变量将具有longjmp时的值,而在cpu寄存器中的变量则恢复为调用setjmp时的值。

不进行优化时,自己主动变量存放在存储器中。

优化后,自己主动变量存放寄存器中,这就是优化编译后auto_data值变为0的原因。

setjmp与longjmp的更多相关文章

  1. C 语言中 setjmp 和 longjmp

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

  2. 非本地跳转之setjmp与longjmp

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

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

  4. C中的setjmp与longjmp

    setjmp与longjmp是属于C语言中的,当然,C++也会有这两个函数了.他们的原型如下: int setjmp( jmp_buf env ); 作用:第一次调佣时,将寄存器的当前状态信息全部存入 ...

  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函数也称为 ...

  10. setjmp和longjmp函数使用详解

    源地址:http://blog.csdn.net/zhuanshenweiliu/article/details/41961975 非局部跳转语句---setjmp和longjmp函数.非局部指的是, ...

随机推荐

  1. 【BZOJ 2186】 2186: [Sdoi2008]沙拉公主的困惑 (欧拉筛,线性求逆元)

    2186: [Sdoi2008]沙拉公主的困惑 Description 大富翁国因为通货膨胀,以及假钞泛滥,政府决定推出一项新的政策:现有钞票编号范围为1到N的阶乘,但是,政府只发行编号与M!互质的钞 ...

  2. JZYZOJ1539[haoi2015]T2 树链剖分

    http://172.20.6.3/Problem_Show.asp?id=1539 在学校的OJ又写了一次,RE了好多次,原来haoi的时候这道题需要开栈+快读,裸数据结构30分,加上快读50分.o ...

  3. 【欧拉回路】Play On Words(6-16)

    [UVA10129]Play On Words 算法入门经典第6章6-16(P169) 题目大意:有一些单词,问能不能将它们串成字符串(只有前缀和后缀相同才能连) 试题分析:很巧妙的一道题,将每个单词 ...

  4. 泛型类Bag

    课堂练习--泛型类Bag 要求: 0.代码运行在命令行中,路径要体现学号信息,IDEA中,伪代码要体现个人学号信息 1.参见Bag的UML图,用Java继承BagInterface实现泛型类Bag,并 ...

  5. 21点游戏java实现

    21点的基本知识 21点是世界上比较流行的扑克游戏项目 除掉大小王的一副扑克牌,共计52张牌 21点不区分花色,其中A----10均代表扑克牌本身的点数J Q K代表10点 区分庄家和闲家,其中闲家可 ...

  6. 星际争霸 虚空之遗 人族5BB 操作流程

    人族5BB rush timing 3min-3min30 一波战术,对面双开不侦察应该就GG了. 14农民BS,建议在第一个BS后的100矿,马上接上一个BS堵口,基本上对面是侦察不到的,特别是内双 ...

  7. 九.Spring Boot JPAHibernateSpring Data

    1.项目结构 2.导入jar包 <!-- 添加Spring-data-jpa依赖. --> <dependency> <groupId>org.springfram ...

  8. 视差映射 parrallax mapping

    算个新的uv在heightmap https://learnopengl.com/Advanced-Lighting/Parallax-Mapping https://blog.csdn.net/so ...

  9. Axure 简单原型设计

    简介 Axure RP是一个专业的快速原型设计工具.Axure(发音:Ack-sure),代表美国Axure公司:RP则是Rapid Prototyping(快速原型)的缩写. Axure RP是美国 ...

  10. scrapy-splash抓取动态数据例子一

    目前,为了加速页面的加载速度,页面的很多部分都是用JS生成的,而对于用scrapy爬虫来说就是一个很大的问题,因为scrapy没有JS engine,所以爬取的都是静态页面,对于JS生成的动态页面都无 ...