C语言异常捕获机制 - setjmp

快速入门

想快速入门该模块请访问:介绍数据接口示例代码

介绍

C语言没有C++或Java的异常捕获机制,但可以通过setjmp/longjmp实现类似的效果:

  • 使用setjmp保存当前执行环境到jmp_buf,然后默认返回0。
  • 程序继续执行,到某个地方调用longjmp,传入上面保存的jmp_buf,以及另一个整形值(我们称他为异常码)。
  • 此时执行点又回到调用setjmp的返回处,且返回值变成longjmp设置的值
  • 可以实现跨函数跳转

注意:

  • 使用gcc或者clang优化编译的时候,可能导致结果不符合预期。可以参考某大神的示例代码。因此不推荐时候,异常捕获最好还是直接使用返回值形式进行调用。https://gist.github.com/nnkken/8aea1eaf1e43a963a9309c98ae4f891e

  • 此外,setjmp只能设置最近一次执行环境,而且longjmp也只能是回到上一次设置setjmp中,因此并不支持设置多个执行环境

数据与接口

头文件

  • #include <setjmp.h>

数据

  • ​环境堆栈类型 : jmp_buf

接口

  • ​设置环境堆栈 int setjmp( jmp_buf env );

  • ​跳转至环境堆栈并返回指定值 void longjmp( jmp_buf env, int value );

接口介绍

setjmp

​ setjmp函数用于保存程序的运行时的堆栈环境,接下来的其它地方,你可以通过调用longjmp函数来恢复先前被保存的程序堆栈环境。当 setjmp和longjmp组合一起使用时,它们能提供一种在程序中实现“非本地局部跳转”(“non-local goto”)的机制。并且这种机制常常被用于来实现,把程序的控制流传递到错误处理模块之中;或者程序中不采用正常的返回(return)语句,或函数的正常调用等方法,而使程序能被恢复到先前的一个调用例程(也即函数)中。

对setjmp函数的调用时,会保存程序当前的堆栈环境到env参数中;接下来调用longjmp时,会根据这个曾经保存的变量来恢复先前的环境,并且当前的程序控制流,会因此而返回到先前调用setjmp时的程序执行点。此时,在接下来的控制流的例程中,所能访问的所有的变量(除寄存器类型的变量以外),包含了longjmp函数调用时,所拥有的变量。

longjmp

​ longjmp函数用于恢复先前程序中调用的setjmp函数时所保存的堆栈环境。setjmp和longjmp组合一起使用时,它们能提供一种在程序中实现“非本地局部跳转”(“non-local goto”)的机制。并且这种机制常常被用于来实现,把程序的控制流传递到错误处理模块,或者不采用正常的返回(return)语句,或函数的正常调用等方法,使程序能被恢复到先前的一个调用例程(也即函数)中。

对setjmp函数的调用时,会保存程序当前的堆栈环境到env参数中;接下来调用longjmp时,会根据这个曾经保存的变量来恢复先前的环境,并且因此当前的程序控制流,会返回到先前调用setjmp时的执行点。此时,value参数值会被setjmp函数所返回,程序继续得以执行。并且,在接下来的控制流的例程中,它所能够访问到的所有的变量(除寄存器类型的变量以外),包含了longjmp函数调用时,所拥有的变量;而寄存器类型的变量将不可预料。setjmp函数返回的值必须是非零值,如果longjmp传送的value参数值为0,那么实际上被setjmp返回的值是1。

伪代码

res = setjmp(env);
if (res == 0) {try dosomething...(contain longjmp)
} else {exception dosomething...
}

示例:比大小

#include <stdio.h>
#include <setjmp.h>#define CORRECT_NUM 5
jmp_buf g_env;void err_1(void)
{printf("raise err 1: num is small\n");longjmp(g_env, 1);
}void err_2(void)
{printf("raise err 2: num is large\n");longjmp(g_env, 2);
}void work_func(int num)
{if (num == CORRECT_NUM) {printf("num is correct\n");} else if (num < CORRECT_NUM) {err_1();} else {err_2();}
}int main() {int num;scanf("%d", &num);int res = setjmp(g_env);if (res == 0) {/* try */work_func(num);} else {/* exception */printf("res = %d\n", res);}return 0;
}

参考链接

  1. https://zhuanlan.zhihu.com/p/82492121
  2. http://www.360doc.com/content/22/0119/23/78473664_1014100527.shtml
  3. https://www.runoob.com/cprogramming/c-standard-library-setjmp-h.html
  4. https://gist.github.com/nnkken/8aea1eaf1e43a963a9309c98ae4f891e

【C语言基础】C语言异常捕获机制 - setjmp相关推荐

  1. 【C语言基础】C语言异常捕获机制 - assert

    C语言异常捕获机制 - assert 快速入门 想快速入门该模块请访问:介绍,数据接口,示例代码 介绍 通常一个良好的代码功能运行环境都有功能运行前检查和运行后检查两个方面.C语言中提供了assert ...

  2. 1,Java语言基础-Java语言概述和必要计算机知识

    Java语言基础 Java语言概述 1,Java语言发展史 Java语言本质 Java是面向对象的高级语言,它是由c和c++发展而来. Java发展语言历史概述 Java 是由 James Gosli ...

  3. 2,Java语言基础-Java语言基本程序设计知识

    Java语言基础 Java语言基本程序设计知识 1,JavaAPI概述 1.1,什么是API API是指应用程序接口( Application Program Interface, API),故名思意 ...

  4. WML语言基础-WML语言基础(WAP建站)

    WML语言基础-WML语言基础(WAP建站)一 作者:青燕    来源:青燕网    更新时间:2007-8-19 19:22:22    浏览次数:255 完成wap服务器的建立和wap浏览器的安装 ...

  5. 用c实现跨平台异常捕获机制

    为什么80%的码农都做不了架构师?>>>    TBOX封装了一套跨平台的异常捕获实现,来模拟windows的seh异常处理功能,而且是线程安全的. 在linux/mac下的实现 使 ...

  6. 用c实现跨平台异常捕获机制 1

    TBOX封装了一套跨平台的异常捕获实现,来模拟windows的seh异常处理功能,而且是线程安全的. 在linux/mac下的实现 使用signal 捕获异常信号 使用sigsetjmp保存现场寄存器 ...

  7. python语言基础-Python语言基础与应用

    spContent=本课基于主讲教师在北京大学讲授数据结构与算法课(Python版)的多年教学实践经验,面向零编程基础的大学生和社会公众,全面讲授Python语言基础,培养学生计算思维的能力,并讲解P ...

  8. 【读书笔记】语言基础- Lua语言入门(一)

    目录 注:本系列为<Lua程序设计-第4版> 的读书笔记,其中的见解有不完善的地方,可以在评论区指出,原版请看图书 Lua运行环境 一. 使用Lua语言解释器运行Lua语言:(下面的实例以 ...

  9. flask基础五之异常捕获和请求勾子

    异常捕获 HTTP 异常主动抛出 abort 方法 抛出一个给定状态代码的 HTTPException 或者 指定响应,例如想要用一个页面未找到异常来终止请求,你可以调用 abort(404). 参数 ...

最新文章

  1. 云南“爆款”景区相继停业整顿 旅游大省为环保让路
  2. BP神经网络-- C语言实现
  3. Qt Creator预览版
  4. 反思快乐:融入 真实 不回忆 聪明应对
  5. 改造独立部署(SCD)模式下.NET Core应用程序 dotnet的exe文件启动过程
  6. Tomcat的Session管理(三)
  7. 机器学习--逻辑斯谛回归(Logistic Regression)
  8. PHP九宫格翻牌抽奖,PHP 九宫格抽奖代码
  9. 网站SEO优化--Flash站优化方法
  10. 基于OpenCV实现二值图细化,骨骼化并求出端点和交叉点
  11. MT6573驱动开发日志之touchpanel
  12. hdoj 1575 Tr A (矩阵快速幂)
  13. word安装到计算机的哪里,如何查找word安装目录 如何查找word的路径
  14. 一款超级好用的虚拟示波器软件
  15. 纪念我的小宝贝——浪浪
  16. 逆反西游无法读取服务器信息,逆反西游
  17. 稿酬模式:UGC时代媒体平台如何供养生产者?
  18. P4383 [八省联考2018]林克卡特树lct 树形DP+凸优化/带权二分
  19. 32 --> 详解 OpenWRT系统框架基础软件模块之netifd
  20. 固定资产的日期之接管日期

热门文章

  1. 阿里工程师太凶残了,竟把服务器泡在“水里”!
  2. Flutter for Web 详细预研
  3. 2021 ISC会上山石网科重磅发布智能下一代防火墙A系列,重新定义边界安全防御
  4. “编程能力差的程序员,90%输在了这点上!”谷歌AI专家:都是瞎努力!
  5. 分布式存储首选,浪潮商用机器FP5466G2服务器测评分析
  6. 西安交大计算机考研分数线2020院线,西安交通大学2020考研复试分数线已公布
  7. app获取个人信息是否合法_重拳出击!42款APP过度收集用户信息被点名
  8. Android自动化打包工具,利用Jenkins实现Android自动化打包
  9. python文件替换一行_python自动化替换文件中每一行中的特有字符串
  10. JWT操作工具类分享