nsetjmp和longjmp函数实现函数之间的跳转(需包含头文件"setjmp.h"):
函数原型:int setjmp(jmp_buf env);
      void longjmp(jmp_buf env, int val);
setjmp函数用于设置跳转的目的位置,longjmp函数进行跳转。
env:保留了需要返回的位置的堆栈情况。
setjmp的返回值:直接调用该函数,则返回0;若由longjmp的调用,导致setjmp被调用,则返回val(longjmp的第二个参数)。
1.longjmp对各类型参数的影响:
考虑下面这个程序:
#include<iostream>#include<setjmp.h>#include<stdlib.h>#include<stdio.h>

using namespace std;

jmp_buf jmpbuffer;

void g(){  cout << "in g()" << endl;

  longjmp(jmpbuffer, 2);}

void f(){  cout << "in f()" << endl;

  g();

  cout << "leave f()" << endl;}

int globval;

int main(){int autoval;  register int regival;volatile int volaval;static int statval;  

  cout << "begin" << endl;

  globval = 90;  autoval = 91;  regival = 92;  volaval = 93;  statval = 94;

int i = setjmp(jmpbuffer);

  cout << "setjmp return code: " << i << endl;

if(2 == i)  {    cout << "error code: "<< i << endl;

    cout << "globval= " << globval << "; ";    cout << "autoval= " << autoval << "; ";    cout << "regival= " << regival << "; ";    cout << "volaval= " << volaval << "; ";    cout << "statval= " << statval << "; " << endl;return 0;  }

  globval = 0;  autoval = 1;  regival = 2;  volaval = 3;  statval = 4;

  cout << "globval= " << globval << "; ";  cout << "autoval= " << autoval << "; ";  cout << "regival= " << regival << "; ";  cout << "volaval= " << volaval << "; ";  cout << "statval= " << statval << "; " << endl;

  f();  

return 0;}

在编译时禁止优化,输出结果如下:

使用O3优化编译,结果如下:

在非优化时,包括寄存器变量(register修饰)在内的所有类型都被存放在内存中,所以所有变量都是更改后的值。

在优化编译时,自动变量(默认类型)和寄存器变量被存储在寄存器中,其它变量与非优化时一样。所以autoval和regival都还原为原来的值。

附jmp_buf结构:

§
typedef struct          {                  unsigned j_sp;  // 堆栈指针寄存器                  unsigned j_ss;  // 堆栈段                  unsigned j_flag;  // 标志寄存器                  unsigned j_cs;  // 代码段                  unsigned j_ip;  // 指令指针寄存器                  unsigned j_bp; // 基址指针                  unsigned j_di;  // 目的指针                  unsigned j_es; // 附加段                  unsigned j_si;  // 源变址                  unsigned j_ds; // 数据段          } jmp_buf; 

保证局部变量在longjmp过程中一直保存它的值的方法:把它声明为volatile变量。(适合那些在setjmp执行和longjmp返回之间会改变的变量)。
存放在内存中的变量,将具有调用longjmp时的值,而在CPU和浮点寄存器中的变量则恢复为调用setjmp函数时的值。
优化编译时,register和auto变量都存放在寄存器中,而volatile变量仍存放在内存。
2.用setjmp和longjmp实现C++异常处理(try/catch)
View Code

#include<setjmp.h>

jmp_buf jmpbuffer;

#define try \int jmp; \    jmp = setjmp(jmpbuffer); \if(0 == jmp) \

#define throw(a) longjmp(jmpbuffer, a);

#define catch(a) \    a = jmp; \if(0 != jmp)

测试(.c文件):
View Code

#include"head.h"#include<setjmp.h>#include<stdlib.h>#include<stdio.h>

void g(){  printf("in g()\n");throw(32);}

void f(){  printf("in f()\n");

  g();

  printf("leave f()\n");}

int main(){  printf("begin\n");

try  {      f();  }catch(int a)  {      printf("in catch: %d\n", a);  }  

return 0;}

转载于:https://www.cnblogs.com/lq0729/archive/2011/10/23/2222117.html

Linux学习之setjmp和longjmp函数相关推荐

  1. Linux学习:文件 I/O 函数

    1.open 函数 (1)头文件: #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> ...

  2. Linux学习日志DAY8

    1)Linux程序设计入门--基础知识 2)Linux程序设计入门--进程介绍 3)Linux程序设计入门--文件操作 4)Linux程序设计入门--时间概念 5)Linux程序设计入门--信号处理 ...

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

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

  4. 递归和函数栈与setjmp和longjmp的关系

    递归每执行一次都会释放一次函数栈 setjmp 记录函数栈的栈顶 longjmp 寻找函数栈的栈顶 如果longjmp找到了他要寻找的函数栈顶 调用setjmp的函数栈不会被释放 所以setjmp 和 ...

  5. 不同函数之间的跳转setjmp和longjmp

    我们学过C语言中的goto,只能当前函数里面跳转是不能跨越函数的.setjmp和longjmp却可以跨越函数跳转. #include <stdio.h> #include <setj ...

  6. Linux学习之exit函数

    From: http://hi.baidu.com/homappy/item/549b37c06865877488ad9e75 若父进程在子进程之前终止了,则子进程的父进程将变为init进程,其PID ...

  7. linux C下的setjmp与longjmp介绍

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

  8. 【Linux学习笔记④】——Shell程序设计【变量 输入与输出 条件表达式 判断语句 循环语句 Shell函数】

    ⌛️ 文章目录 一.Shell 概述 二.Shell 脚本的定义与执行 2.1 Shell 脚本的定义 2.2 Shell 脚本的执行 三.Shell 变量 3.1 用户自定义变量 3.2 环境变量 ...

  9. Linux学习-文件IOA1——用结构体和文件操作函数实现文件的拷贝

    Linux学习-文件IOA1--用结构体和文件操作函数实现文件的拷贝 其实我们不必选用结构体去实现模仿拷贝功能的,但是为了锻炼我们的思维以及对结构体.文件操作函数的使用,所以我们就这样来折腾自己. 学 ...

最新文章

  1. 改变mac中launchpad图标大小
  2. Webpack 4.0 打包 Vue 应用时出现无法使用Vue-loader问题及解决方法
  3. VScode使用python的yapf库
  4. 『设计模式』--常见面向对象设计原则
  5. 【啊哈!算法】之二、插入排序
  6. 艾伦图灵_Java英雄:丹·艾伦
  7. 通过源码将git升级到最新版
  8. java对象深克隆_JAVA中对象的克隆及深拷贝和浅拷贝
  9. 中getname_浅析JS中的class
  10. android 防止重复启动app,Android应用开发Android 防止启动页面(SplashActivity)被多次启动...
  11. u-boot移植随笔:使用svn进行版本控制
  12. 机器学习入门(二):工具与框架的选择
  13. JavaScript DOM(一)
  14. C#弹出窗体、C#导出Excel、C#数据展示框、C#弹出框
  15. DSP28335代码生成——如何使用两个中断
  16. 捣鼓小米路由器开发版本
  17. 微店关键词取商品列表API接口(item_search-根据关键词取商品列表API接口),微店API接口
  18. 案例——蚂蚁金服初探,唯一的金融互联网生态...
  19. 在Windows Server 2019上部署Deskpool桌面云系统
  20. God.org单域环境攻略(一)

热门文章

  1. 微软hackathon_武汉Hackathon的黑客之路–开发人员如何抗击COVID-19
  2. 1035 Password
  3. CSP 201812-2 小明放学 Python实现+详解
  4. CSP 201909-2 小明种苹果(续)Python实现+详解
  5. mysql complete_mysql 无意重启 [Note] /usr/sbin/mysqld: Normal shutdown
  6. led伏安特性实验误差分析_检测实验室误差分析知识汇编
  7. Python入门学习方法有哪些?
  8. 常用MySQL的命令集锦
  9. Kubernetes基于Metrics Server的HPA
  10. Bminer 7.0.0 ETH挖矿教程(Linux 64)