异常处理
异常安全
一段代码是 异常安全的 ,如果这段代码运行时的失败不会产生有害后果,如内存泄露、存储数据混淆、或无效的输出。异常安全可分成不同层次:
失败透明(failure transparency) ,也称作 不抛出保证(no throw guarantee) :代码的运行保证能成功并满足所有的约束条件,即使存在异常情况。如果出现了异常,将不会对外进一步抛出该异常。(异常安全的最好的层次)
提交或卷回的语义(commit or rollback semantics) ,或称作 强异常安全(strong exception safety) 或 无变化保证(no-change guarantee) :运行可以是失败,但失败的运行保证不会有负效应,因此所有涉及的数据都保持代码运行前的初始值。
基本异常安全(basic exception safety) :失败运行的已执行的操作可能引起了副作用,但会保证状态不变。所有存储数据保持有效值,即使这些数据与异常发生前的值有所不同。
最小异常安全(minimal exception safety) 也称作 无泄漏保证(no-leak guarantee) :失败运行的已执行的操作可能在存储数据中保存了无效的值,但不会引起崩溃,资源不会泄漏。
异常不安全(no exception safety) :没有保证(最差的异常安全层次)。
例如,考虑一个smart vector类型,如C++"s std::vector 或Java"s ArrayList 。当一个数据项 x 插入vector v ,必须实际增加 x 的值到vector的内部对象列表中并且修改vector的计数域以正确表示 v 中保存了多少数据项;此时如果已有的存储空间不够大,就需要分配新的内存。内存分配可能会失败并抛出异常。因此,vector数据类型如果是“失败透明”保证将会非常困难甚至不可能实现。但vector类型提供“强异常安全”保证却是相当容易的;在这种情况下, x 插入 v 或者成功,或者 v 保持不变。如果vector类型仅提供“基本异常安全”保证,如果数据插入失败, v 可能包含也可能不包含 x 的值,但至少 v 的内部表示是一致的。但如果vector数据类型是“最小异常安全”保证, v 可能会是无效的,例如 v 的计数域被增加了,但 x 并未实际插入,使得内部状态不一致。对于“异常不安全”的实现,程序可能会崩溃,例如写入数据到无效的内存。
通常至少需要基本异常安全。失败透明是难于实现的,特别是在编写库函数时,因为对应用程序的复杂知识缺少获知。
程序设计语言的异常机制
许多常见的程序设计语言,包括Actionscript,Ada,BlitzMax,C++,C#,D,ECMAScript,Eiffel,Java,ML,Object Pascal(如Delphi,Free Pascal等),Objective-C,Ocaml,PHP(version 5),PL/1,Prolog,Python,REALbasic,Ruby,Visual Prolog以及大多数.NET程序设计语言,内建的异常机制都是沿着函数调用栈的函数调用逆向搜索,直到遇到异常处理代码为止。一般在这个异常处理代码的搜索过程中逐级完成栈卷回(stack unwinding)。但Common Lisp是个例外,它不采取栈卷回,因此允许异常处理完后在抛出异常的代码处原地恢复执行。而Visual Basic(尤其是在其早于 .net 的版本,例如 6.0 中)走得更远: on error 语句可轻易指定发生异常后是重试( resume )还是跳过( resume next )还是执行程序员定义的错误处理程序( goto *** )。
多数语言的异常机制的语法是类似的:用 throw 或 raise 抛出一个异常对象(Java或C++等)或一个特殊可扩展的枚举类型的值(如Ada语言);异常处理代码的作用范围用标记子句( try 或 begin 开始的语言作用域)标示其起始,以第一个异常处理子句( catch, except, rescue 等)标示其结束;可连续出现若干个异常处理子句,每个处理特定类型的异常。某些语言允许 else 子句,用于无异常出现的情况。更多见的是 finally, ensure 子句,无论是否出现异常它都将执行,用于释放异常处理所需的一些资源。
C++异常处理是资源获取即初始化(Resource-Acquisition-Is-Initialization)的基础。
C语言一般认为是不支持异常处理的。Perl语言可选择支持结构化异常处理(structured exception handling)。
Python语言对异常处理机制是非常普遍深入的,所以想写出不含 try, except 的程序非常困难。
免责声明:以上内容版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。感谢每一位辛勤著写的作者,感谢每一位的分享。
- 有价值
- 一般般
- 没价值