[原创]C语言异常处理机制——为您的C程序添加异常处理

作者在 2006-09-26 09:45:00 发布以下内容



C语言异常处理机制——为您的C程序添加异常处理

1、什么是异常

        异常一般指的是程序运行期(Run-Time)发生的非正常情况。
        异常一般是不可预测的,如:内存不足、打开文件失败、范围溢出等。
        UNIX 使用信号给出异常,并当发生异常时转跳到信号处理过程进行异常处理。DOS下的信号对比UNIX系统而言相对较少。
        C标准库提供两个特殊的函数:setjmp() 及 longjmp(),这两个函数是结构化异常的基础,正是利用这两个函数的特性来实现异常。
        所以,异常的处理过程可以描述为这样:
        首先设置一个跳转点(setjmp() 函数可以实现这一功能),然后在其后的代码中任意地方调用 longjmp() 跳转回这个跳转点上,以此来实现当发生异常时,转到处理异常的程序上,在其后的介绍中将介绍如何实现。
        setjmp() 为跳转返回保存现场并为异常提供处理程序,longjmp() 则进行跳转(抛出异常),setjmp() 与 longjmp() 可以在函数间进行跳转,这就像一个全局的 goto 语句,可以跨函数跳转。
        举个例子,程序在 main() 函数内使用 setjmp() 设置跳转,并调用另一函数A,函数A内调用B,B抛出异常(调用longjmp() 函数),则程序直接跳回到 main() 函数内使用 setjmp() 的地方返回,并且返回一个值。

2、jmp_buf 异常结构

        使用 setjmp() 及 longjmp() 函数前,需要先认识一下 jmp_buf 异常结构。jmp_buf 将使用在 setjmp() 函数中,用于保存当前程序现场(保存当前需要用到的寄存器的值),jmp_buf 结构在 setjmp.h 文件内声明:

        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;

        jmp_buf 结构存放了程序当前寄存器的值,以确保使用 longjmp() 后可以跳回到该执行点上继续执行。

3、setjmp() 与 longjmp() 函数详细说明

        setjmp() 与 longjmp() 函数原型如下:
                void _Cdecl longjmp(jmp_buf jmpb, int retval);
                int _Cdecl setjmp(jmp_buf jmpb);

        _Cdecl 声明函数的参数使用标准C的进栈方式(由右向左)压栈,_Cdecl 是C语言的一种调用约定,除此以

C/C++ | 阅读 4466 次
文章评论,共4条
ChenMo(作者)
2006-09-26 20:21
1
<div class='quote'><strong>以下引用穆扬(游客)在2006-9-26 6:44:00发表的评论:</strong><br /><br />奇怪了,这个幼儿园不但有小朋友居然还有个把阿姨? </div>

穆扬网友有更好的实现?
老实说我对这实现并不满意,
我希望看到更好的,不妨给点意见。
ChenMo(作者)
2006-09-27 05:19
2
使用结构体与函数指针可以粗糙地“仿制”对象,也很有意思。
然而因为C语言本身问题,估计这样做的意义不大,
有点像是穿上凤凰袍子的鸡——或者是穿上鸡袍子的凤凰。

玩一下觉得好玩那不管如何值得研究一番。
那怕是异常,意义也不见得大,我自己也不常用它。
只是个人兴趣才写这篇东西,纯粹的玩。
海啸南风
2006-10-03 08:26
3
原创吗?!
佩服,支持!
麻烦借我转一贴,我会注明出处的。
特别喜欢搜集像你这样高手的经验谈,回去我会好好研究的。

欢迎常来我的blog切磋:42514.bc-cn.net

十分感谢!
helengreens
2008-06-24 02:23
4
为什么后面没有了?
游客请输入验证码