第1部分 原理与实现:通用仿真库
第2章 代码概述
2.3.6 计算异常与诊断信息
在计算过程中,有时会出现一些事件使计算无法进行下去或者计算错误,例如在除法中遇到被零除、计算结果超出表示范围等,这些事件被称为计算异常(注意,这里的异常仅指溢出之类与计算有关的异常,不是指非法指针访问之类的系统异常)。显然,一个稳定可靠的,计算系统必须处理计算异常,而如何处理计算异常的关键问题是你以什么观点看待它们:
(1)一般很少发生,即使发生了,代码的用户(更高层次的开发员)应该知道并处理它。随这种观点而来的自然是最简单的处理方式,即忽略它。
(2)是一种严重的错误,计算需要立刻停止以进行错误处理。在c++中,抛出异常是非常适合这种观点的处理方式。
(3)可能造成错误,但没有严重到需要停止计算的地步。当异常发生时,计算应当继续进行,但返回结果的同时也发出警告。
方式(1)是最常见也最容易实现的方式,但它给后续的开发带来不便。高层开发员可能需要编写计算异常的检测代码。通常,检测代码的层次越高,效率就越低,编程越困难。方式(2)过于敏感,如果某些用户并不关心计算异常,没有编写相应的计算异常处理代码,那么这个抛出的异常将破坏程序的流程,通常会导致程序终止。另外,编写异常处理代码也会提高计算代码在组织或阅读上的难度。方式(3)比较折中,而且在需要时,可以方便地转换为方式(1)或方式(2)。例如,如果你不关心,那么简单地忽略警告即可;如果你极其关切,那么可以在得到警告时再抛出异常。本书代码就使用了方式(3),而这意味着除了返回一个值之外,还需要设置一些诊断信息供用户查询,以保证用户可以检查计算结果。
信息均存在维护的问题。系统提供诊断信息的目的,是为了在出错时提示用户错误所在,而什么时候进行检测则是用户决定的,系统无法确定,故一般系统要保留相关信息以待用户提取,直到有新信息产生时,才会明确清除旧信息。这种特性使得诊断信息的维护有点困难。如果用户得到了诊断信息,却不知道信息是当前产生的还是以前遗留的,那么这些信息除了使他困惑之外还能有什么用处呢?有两种维护方式可以避免这种局面:
一是在每个接口函数中进行维护,即在每个接口函数的入口处明确清除以前遗留的信息。这样处理以后,用户每次得到的信息总是最新的(Win32 API就是这样处理的)。
……
展开