setjmp与longjmp
在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的更多相关文章
- C 语言中 setjmp 和 longjmp
在 C 语言中,我们不能使用 goto 语句来跳转到另一个函数中的某个 label 处:但提供了两个函数——setjmp 和 longjmp来完成这种类型的分支跳转.后面我们会看到这两个函数在处理异常 ...
- 非本地跳转之setjmp与longjmp
非本地跳转(unlocal jump)是与本地跳转相对应的一个概念. 本地跳转主要指的是类似于goto语句的一系列应用,当设置了标志之后,可以跳到所在函数内部的标号上.然而,本地跳转不能将控制权转移到 ...
- 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 ...
- C中的setjmp与longjmp
setjmp与longjmp是属于C语言中的,当然,C++也会有这两个函数了.他们的原型如下: int setjmp( jmp_buf env ); 作用:第一次调佣时,将寄存器的当前状态信息全部存入 ...
- setjmp 与 longjmp
setjmp和longjmp是C语言独有的,只有将它们结合起来使用,才能达到程序控制流有效转移的目的,按照程序员的预先设计的意图,去实现对程序中可能出现的异常进行集中处理. 先来看一下这两个函数的定义 ...
- setjmp和longjmp的使用
问题描述: setjmp和longjmp的使用 问题解决: setjmp和longjmp是C语言独有的,只有将它们结合起来使用,才能达到程序控制流有效转移的目的,按照程序 ...
- 【转】浅析C语言的非局部跳转:setjmp和longjmp
转自 http://www.cnblogs.com/lienhua34/archive/2012/04/22/2464859.html C语言中有一个goto语句,其可以结合标号实现函数内部的任意跳转 ...
- 【转载】setjmp和longjmp函数使用详解
[说明]本文上半部分转载自 wykwdy007 的转载文章 http://blog.csdn.net/wykwdy007/article/details/6535322 --------------- ...
- 进程环境之setjmp和longjmp函数
在C中,goto语句是不能跨越函数的,而执行这样跳转功能的是函数setjmp和longjmp.这两个函数对于处理发生在深层嵌套函数调用中的出错情况是非常有用的. setjmp和longjmp函数也称为 ...
- setjmp和longjmp函数使用详解
源地址:http://blog.csdn.net/zhuanshenweiliu/article/details/41961975 非局部跳转语句---setjmp和longjmp函数.非局部指的是, ...
随机推荐
- 洛谷 P3943 星空
题目背景 命运偷走如果只留下结果, 时间偷走初衷只留下了苦衷. 你来过,然后你走后,只留下星空. 题目描述 逃不掉的那一天还是来了,小 F 看着夜空发呆. 天上空荡荡的,没有一颗星星——大概是因为天上 ...
- struts2和spring整合错误 org.springframework.beans.factory.BeanCreationException,已解决
先贴上错误 2018-8-16 23:41:10 org.springframework.context.support.ClassPathXmlApplicationContext prepareR ...
- 8VC Venture Cup 2016 - Elimination Round B. Cards 瞎搞
B. Cards 题目连接: http://www.codeforces.com/contest/626/problem/B Description Catherine has a deck of n ...
- 最简单的flask表单登录
from flask import Flask from flask import request app = Flask(__name__) @app.route('/', methods=['GE ...
- 大于非负整数N的第一个回文数 Symmetric Number
1.题目 如标题,求大于整数N(N>=0)的第一个回文数的字符串表示形式. 2.样例 1 --> 2 9 -->11 12345 -->12421 123456 --> ...
- The Responsive jQuery Content Slider
jquery slider 效果 http://bxslider.com/ http://www.cnblogs.com/lhb25/archive/2012/08/13/jquery-image-e ...
- nio selector
为什么使用Selector? 仅用单个线程来处理多个Channels的好处是,只需要更少的线程来处理通道.事实上,可以只用一个线程处理所有的通道.对于操作系统来说,线程之间上下文切换的开销很大,而且每 ...
- IOS Reachability判断所请求服务器是否超时?
开发Web等网络应用程序的时候,需要确认网络环境,连接情况等信息.如果没有处理它们,是不会通过Apple的审查的. Apple 的 例程 Reachability 中介绍了取得/检测网络状态的方法. ...
- [转]SSIS: By coding
本文转自:http://www.codeproject.com/Articles/604197/SSIS-By-coding Introduction SSIS better known as “SQ ...
- android 启动socket 失败:socket(af_inet sock_stream 0) 返回-1
Android 启动socket 失败:socket(af_inet sock_stream 0) 返回-1 原因权限问题, 应该添加如下权限: <uses-permission android ...