C++编译器如何实现异常处理
Posted on 八月 16rd, 2007 由 admin
热门问答:
推荐阅读
| · java异常处理的陋习展播 |
| 摘要: 你觉得自己是一个java专家吗?是否肯定自己已经全面掌握了java的异常处理机制?在下面这段代码中,你能够迅速找出异常处理的六个问题吗? 作为一个java程序员,你至少应该能够找出两个问题。但是,如果你不能找出全部六个问题,请继续阅读本文。 本文讨论的不是java异常处理的一般性原则,因为这些原则已经被大多数人熟知。我们要做的是分析各种可称为“反例”(anti-pattern)的违背优秀编码规范的常见坏习...... |
| · 短信保存技巧 |
| 摘要:安装完7050的3.06b联机软件后,有一个叫“lgems”的软件,我们可以利用它把一些搞笑、有趣、经常用到的或网上拉下来的短信息保存到手机中短信草稿箱里去,以备不时之需,很简单,只需几个步骤就可以完成。 1:联机。2:打开“lgems”后,直接点击新键选项,如图1,在输入框里输入想保存的短信,或直接把网上的粘贴到上面。3:最后点击保存选项,(不...... |
正文
与传统语言相比,c++的一项革命性创新就是它支持异常处理。传统的错误处理方式经常满足不了要求,而异常处理则是一个极好的替代解决方案。它将正常代码和错误处理代码清晰的划分开来,程序变得非常干净并且容易维护。本文讨论了编译器如何实现异常处理。我将假定你已经熟悉异常处理的语法和机制。本文还提供了一个用于vc++的异常处理库,要用库中的处理程序替换掉vc++提供的那个,你只需要调用下面这个函数:
之后,程序中的所有异常,从它们被抛出到堆栈展开(stack unwinding),再到调用catch块,最后到程序恢复正常运行,都将由我的异常处理库来管理。
与其它c++特性一样,c++标准并没有规定编译器应该如何来实现异常处理。这意味着每一个编译器的提供商都可以用它们认为恰当的方式来实现它。下面我会描述一下vc++是怎么做的,但即使你使用其它的编译器或操作系统①,本文也应该会是一篇很好的学习材料。vc++的实现方式是以windows系统的结构化异常处理(seh)②为基础的。
结构化异常处理—概述
在本文的讨论中,我认为异常或者是被明确的抛出的,或者是由于除零溢出、空指针访问等引起的。当它发生时会产生一个中断,接下来控制权就会传递到操作系统的手中。操作系统将调用异常处理程序,检查从异常发生位置开始的函数调用序列,进行堆栈展开和控制权转移。windows定义了结构“exception_registration”,使我们能够向操作系统注册自己的异常处理程序。
注册时,只需要创建这样一个结构,然后把它的地址放到fs段偏移0的位置上去就行了。下面这句汇编代码演示了这一操作:
mov fs:[0], exc_regp
prev字段用于建立一个exception_registration结构的链表,每次注册新的exception_registration时,我们都要把原来注册的那个的地址存到prev中。
那么,那个异常回调函数长什么样呢?在excpt.h中,windows定义了它的原形:
不要管它的参数和返回值,我们先来看一个简单的例子。下面的程序注册了一个异常处理程序,然后通过除以零产生了一个异常。异常处理程序捕获了它,打印了一条消息就完事大吉并退出了。
注意exception_registration必须定义在栈上,并且必须位于比上一个结点更低的内存地址上,windows对此有严格要求,达不到的话,它就会立刻终止进程。


讨论区