setjmp和longjmp函数
关于setjmp函数和longjmp函数有话要说,是UNIX高级环境变成看到了10.10信号那章用到了,研究一下,这里作为补充。
setjmp(jmp_buf env_buf) 函数可以将当前的运行环境存入jmp_buf变量中,函数默认返回值是返回0。直到longjmp修改该值(!0)后会调回setjmp函数处。
jmp_buf,是某种形式的数组,其中存放在调用longjmp时能用来恢复栈状态的所有信息。
那么,当jmp回来后原函数定义的变量是怎样变化的捏??(答案是:不一定)这里又用几个不同类型的变量来看一下。+编译器优化对运行结果产生的影响。
代码如下:
#include <stdio.h>
#include <setjmp.h> static jmp_buf jmp_env; static void f1(int ,int ,int , int );
static void f2(void); static int globval = ; int main(void)
{
/* 4 kinds variables*/
int autoval = ;
register int regival = ;
volatile int volaval = ;
static int statval = ;
int retval;
if ( retval = setjmp(jmp_env) ){ /* default value is 0, so this will run when returns from longjmp()*/
printf("after longjmp: %d\n", retval);
printf("globval=%d,autoval=%d,regival=%d,volaval=%d,statval=%d\n",globval,autoval,regival,volaval,statval);
//exit(0);
return ;
}
/*
* Change variables's value before calc longjmp.
*/
globval = ; autoval = ; regival = ; volaval = ; statval = ;
f1(autoval, regival, volaval, statval);
return ;
} static void f1(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);
f2();
} static void f2()
{
printf("in f2():\n");
longjmp(jmp_env, );
}
结果如下:

分析一下:gcc 直接编译没有进行优化,所有变量都会被更改;
gcc -O 使用编译器优化,其中一种优化包括使用寄存器中的int值来读取,而不是去存储器中读变量。导致这里取到的普通局部变量和寄存器变量是之前的值,并不是更新之后的最新值。
大多实现并不回滚到这些自动变量和寄存器变量的值,不想使其回滚的话有两种方法:
1.声明为静态变量static
2.声明为全局变量
3.声明为volatile变量(volatile)作为指令关键字,确保本条指令不会因编译器的优化而省略,且要求每次直接读值。这是用来防编译器优化的!!!如果要
编写一个非局部跳转的可移植程序必须要使用volaitle关键字
setjmp和longjmp函数的更多相关文章
- 【转载】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函数.非局部指的是, ...
- 学习之"setjmp和longjmp函数"
Linux学习之"setjmp和longjmp函数" 转贴,原文地址:http://www.cnblogs.com/lq0729/archive/2011/10/23/2222 ...
- setjmp()和longjmp()函数
之前我们讲到了过程活动记录(AR),那么如何来操纵AR呢,一个可能的方法是,根据局部变量的地址进行推算,例如对于上面的a函数,执行a函数时的当前AR地址就是参数i的地址偏移8个字节,也就是 ((cha ...
- linux系统编程:setjmp和longjmp函数用法
#include <stdio.h> #include <setjmp.h> //jmp_buf:数组,保存栈信息即运行环境 jmp_buf buf; double Divid ...
- 非本地跳转之setjmp与longjmp
非本地跳转(unlocal jump)是与本地跳转相对应的一个概念. 本地跳转主要指的是类似于goto语句的一系列应用,当设置了标志之后,可以跳到所在函数内部的标号上.然而,本地跳转不能将控制权转移到 ...
- C语言中setjmp与longjmp学习笔记
C语言中setjmp与longjmp学习笔记 一.基础介绍 头文件:#include<setjmp.h> 原型: int setjmp(jmp_buf envbuf) ,然而longjm ...
- setjmp与longjmp
在C中有时我们会使用goto语句用于运行跳转,可是不能跨越函数 #include <stdio.h> void func2() { int num = 0; dst2: if (num & ...
随机推荐
- [luoguP1029] 最大公约数和最小公倍数问题(数论)
传送门 一.暴力枚举(加了点优化) #include <cstdio> int x, y, ans; inline int gcd(int x, int y) { return !y ? ...
- noip模拟赛 花
[问题描述]商店里出售n种不同品种的花.为了装饰桌面,你打算买m支花回家.你觉得放两支一样的花很难看,因此每种品种的花最多买1支.求总共有几种不同的买花的方案?答案可能很大,输出答案mod p的值. ...
- [bzoj1084][SCOI2005]最大子矩阵(DP)
题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1084 分析: m=1时:相当于只有一行数,让你取出p段,使得总和最大 明显可以DP,f ...
- HDU 1546 Idiomatic Phrases Game 求助!help!!!
Idiomatic Phrases Game Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/O ...
- [Elasticsearch] 集群的工作原理 - 第一部分
本文翻译自Elasticsearch官方指南的life inside a cluster一章. ES就是为高可用和可扩展而生的. 扩展能够通过购置性能更强的server(垂直扩展或者向上扩展,Vert ...
- [C++] 自己主动关闭右下角弹窗
近期腾讯.迅雷等各种client,都越发喜欢在屏幕的右下角弹框了. 有骨气的人当然能够把这些软件卸载了事,可是这些client在某些情况下却又还是实用的.怎么办呢? 作为码农,自己实现一个自己主动关闭 ...
- VFL演示样例
上篇文章向大家介绍了VFL的基本的语法点,假设对下面演示样例不熟的童鞋,能够前去參考.废话不多说.我们直接来看演示样例. 演示样例一 将五个大小同样.颜色不同的view排成一行,view间的间隔为15 ...
- 扩展VirtualBox中的centos硬盘大小
一.克隆文件 我之前安装的时候建的是centos 6.3.可是后来空间不够,没办法,又不想重装centos.由于好多东西要配置,特麻烦,所以先想到了使用resize命令,可是在win8中运行D:\Pr ...
- LeetCode 234. Palindrome Linked List (回文链表)
Given a singly linked list, determine if it is a palindrome. Follow up:Could you do it in O(n) time ...
- HDU - 3631 Shortest Path(Floyd最短路)
Shortest Path Time Limit: 1000MS Memory Limit: 32768KB 64bit IO Format: %I64d & %I64u SubmitStat ...