C语言中的set jmp()和long jmp()_Aiden御舟的博客-程序员宝宝

技术标签: C/C++  

与刺激的abort()和exit()相比,goto语句看起来是处理异常的更可行方案。不幸的是,goto是本地的:它只能跳到所在函数内部的标号上,而不能将控制权转移到所在程序的任意地点(当然,除非你的所有代码都在main体中)。

  为了解决这个限制,C函数库提供了setjmp()和longjmp()函数,它们分别承担非局部标号和goto作用。头文件<setjmp.h>申明了这些函数及同时所需的jmp_buf数据类型。
  原理非常简单:
  1.setjmp(j)设置“jump”点,用正确的程序上下文填充jmp_buf对象j。这个上下文包括程序存放位置、栈和框架指针,其它重要的寄存器和内存数据。当初始化完jump的上下文,setjmp()返回0值。
  2. 以后调用longjmp(j,r)的效果就是一个非局部的goto或“长跳转”到由j描述的上下文处(也就是到那原来设置j的setjmp()处)。当作为长跳转的目标而被调用时,setjmp()返回r或1(如果r设为0的话)。(记住,setjmp()不能在这种情况时返回0。)
  通过有两类返回值,setjmp()让你知道它正在被怎么使用。当设置j时,setjmp()如你期望地执行;但当作为长跳转的目标时,setjmp()就从外面“唤醒”它的上下文。你可以用longjmp()来终止异常,用setjmp()标记相应的异常处理程序。
  #include <setjmp.h>
  #include <stdio.h>
  jmp_buf j;
  void raise_exception(void)
  {
  printf("exception raised\n");
  longjmp(j, 1); /* jump to exception handler */
  printf("this line should never appear\n");
  }
  int main(void)
  {
  if(setjmp(j) == 0)
  {
  printf("\''setjmp\'' is initializing \''j\''\n");
  raise_exception();
  printf("this line should never appear\n");
  }
  else
  {
  printf("''setjmp'' was just jumped into\n");
  /* this code is the exception handler */
  }
  return 0;
  }
  /* When run yields:
  ''setjmp'' is initializing ''j''
  exception raised
  ''setjmp'' was just jumped into
  */
  那个填充jmp_buf的函数不在调用longjmp()之前返回。否则,存储在jmp_buf中的上下文就有问题了:
  jmp_buf j;
  void f(void)
  {
  setjmp(j);
  }
  int main(void)
  {
  f();
  longjmp(j, 1); /* logic error */
  return 0;
  }
  所以,你必须把setjmp()处理成只是到其所在位置的一个非局部跳转。
  Longjmp()和setjmp()联合体运行于异常生命期的2和3阶段。longjmp(j,r)产生异常对象r(一个整数),并且作为返回值传送到setjmp(j)处。实际上,setjmp()函数通报了异常r。
  下面这个例子采用switch,能更好的展现这对函数的功能:
  #include <setjmp.h>
  #include <stdio.h>
  jmp_buf j;
  void raise_exception(void)
  {
  printf("exception raised\n");
  longjmp(j, 3); /* jump to exception handler case 3 */
  printf("this line should never appear\n");
  }
  int main(void)
  {
  switch (setjmp(j))
  {
  case 0:
  printf("''setjmp'' is initializing ''j''\n");
  raise_exception();
  printf("this line should never appear\n");
  case 1:
  printf("Case 1\n");break;
  case 2:
  printf("Case 2\n");break;
  case 3:
  printf("Case 3\n");break;
  default:
  break;
  }
  return 0;
  }
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/owen5630/article/details/13624147

智能推荐

Linux_SquidProxyServer代理服务器_范桂飓的博客-程序员宝宝

目录目录Squid proxy serverWeb proxy server operating principleSquid featuresSetup squid serverSetup transparent proxySquit authenticationSetup the Reverse Proxy ServerCase set the transparent proxy

趣图:这个程序很简单呀,看我的_java面试笔试的博客-程序员宝宝

趣图:刚写了一段代码,第一次运行……趣图:新手程序员第一次做项目的过程 ...

python 过采样 权重实现_假设原始数据正负样本1000:1。是直接训练还是先做不平衡处理(比如采样)?..._weixin_39796652的博客-程序员宝宝

不平衡数据集是机器学习中需要解决的常见问题之一。常见的机器学习模型,在处理不平衡数据集时,如果单纯使用精确度来评估模型,往往会对最终结果产生误导。因而,在训练集极度不平衡的情况下,比如原始样本正负样本数量比为10000:1,我们往往可以采用如下几种方法来处理:1. 尽量使用多个指标评估模型在处理分类问题时,单纯使用模型精确度会对结果产生误导。因而可以使用混淆矩阵(confusion matrix)...

[NPUCTF2020]Classical Cipher_Ju4tF0rk的博客-程序员宝宝

[NPUCTF2020]Classical Cipher附件:key.txt:解密后的flag请用flag{}包裹压缩包密码:gsv_pvb_rh_zgyzhs对应明文: ***_key_**_******词频分析得到压缩包密码:第一个尝试无果,发现第二个才是正确的密码:the_key_is_atbash猪圈加动物????解密得到flag:classicalcode根据题目要求套上flag提交即可!...

'>=' not supported between instances of 'str' and 'int'_官爷的博客-程序员宝宝

今天遇到一个bug 后来了解到 input 输入的是str类型的   要想实现&amp;gt;= 就要换成int 类型

随便推点

Xcode命令Archive导出4个ipa包的含义_FreeTourW的博客-程序员宝宝_xcode 导出archive

在archive时候导包需要选择类型,下面是导出4个包的含义,每一个包都有具体的含义:1.Save for iOS App Store Deployment保存到本地 准备上传App Store 或者在越狱的iOS设备上使用2.Save for Ad Hoc Deployment保存到本地 准备在账号添加的可使用设备上使用(具体为在开发者账户下添加可用设备的udid),该app包是发布证书编译

112.Path Sum_Hcaroline的博客-程序员宝宝

problems:Given a binary tree and a sum, determine if the tree has a root-to-leaf path such that adding up all the values along the path equals the given sum.Note: A leaf is a node with no children....

转自baidu wqqq 给软件开发初学者_alienjjj的博客-程序员宝宝

在论坛上呆久了,发现很大一部分有关开发的帖子都是有关心怀梦想,立志成为一个软件英雄或者响当当的黑客人物;或者是狂热的游戏玩家,突然想迈入游戏开发的殿堂,自己打造一个完美的游戏;或者被以前IT行业的“钱”途无量所吸引,为了经济因素希望成为一个程序员的,而寻求进入软件开发领域之门的求助帖子。 这些诸如“你好,我想做程序员,应该怎么做?”,“初学C++,请问看什么书好”,“请高手帮我看看这个程序”,“我...

win8/10 bcdboot引导修复命令的原理和使用方法_dengji2627的博客-程序员宝宝

win8/10 bcdboot引导修复命令的原理和使用方法【迅维网原创文章禁止转载】(本文所述已用UEFI+GPT、BIOS+MBR,WIN10 64位企业版和专业版测试过)  在win8/10系统中有一条BCDboot.exe命令,它是一种快速设置系统启动分区或修复系统启动环境的命令行工具。BCDboot.exe命令是通过从已安装的Windows系统文件夹中复制一小部分启动环境文件...

推荐文章

热门文章

相关标签