第八章 异常控制流 第六节 非本地跳转

1、非本地跳转的作用

是C提供的一种用户级异常控制流的形式。它将控制直接从一个函数转移到另一个当前正在执行的函数, 而不需要经过正常的调用-返回序列

2、非本地跳转的实现

C中通过setjmp和longjmp函数来实现。
在这里插入图片描述

1. setjmp 函数

setjmp函数在env缓冲区中保存当前调用环境, 以供后面的longjmp使用, 并返回
0。调用环境包括程序计数器、栈指针和通用目的寄存器。

setjmp返回的值不能被赋值给变量,不过它可以安全地用在switch或条件语句的测试中

2. longjmp函数

在这里插入图片描述
longjmp函数从env缓冲区中恢复调用环境, 然后触发一个从最近一次初始化env
的setjmp调用的返回。然后setjmp返回, 并带有非零的返回值retval。

3. 二者关系与示例

setjmp函数只被调用一次, 但返回多次: 一次是当第一次调用setjmp, 而调用环境保存在缓冲区env中时,一次是为每个相应的longjmp调用。另一方面, longjmp函数被调用一次, 但从不返回。在这里插入图片描述
在这里插入图片描述
第一次调用setjmp时返回0,调用foo,如果foo出现错误,longjmp会调用最近的setjmp,又回到switch语句中,bar中出错同理。

4. 问题

由于这样的跳转,可能某些本应该在结束时释放的资源会被跳过,造成内存泄漏。

3、应用

1. 允许从深层嵌套的函数调用中立即返回

是允许从一个深层嵌套的函数调用中立即返回, 通常是由检测到某个错误情况引起的。如果在一个深层嵌套的函数调用中发现了一个错误情况,我们可以使用非本地跳转直接返回到一个普通的本地化的错误处理程序, 而不是费力地解开调用栈

2. 使一个信号处理程序分支返回到特殊位置

使一个信号处理程序分支到一个特殊的代码位置, 而不是返回到被信号到达中断了的指令的位置。例子如下
在这里插入图片描述
操作结果是这样的
在这里插入图片描述
说明:
为了避免竞争, 必须在调用了sigsetjmp之后再设置处理程序。否则, 就会冒在初始调用sigsetjmp为siglongjmp设置调用环境之前运行处理程序的风险。也就是还没调用sigsetjmp的时候就按下Ctrl+C

4、C++与Java中的软件异常

C++和Java提供的异常机制是较高层次的, 是C语言的setjmp和longjmp函数
的更加结构化的版本。你可以把try语句中的catch子句看做类似于setjmp函数。相
似地, throw语句就类似于longjmp函数。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值