《Design by Contract for Embedded Software》 翻译( 五 )


关于软件契约(C/C++中的断言),最重要的一点是,它们既不能处理也不能防止错误,就像人与人之间的契约不能防止欺诈一样 。例如,断言成功的内存分配 。ALLEGE ((foo = new Foo) != NULL),可能会给你一种温暖和模糊的感觉,你已经处理或防止了一个错误,而事实上,你没有 。然而,你确实建立了一个契约,在这个契约中,你阐明了在代码中的这个位置无法动态分配对象 Foo 是一个错误 。从那时起,契约将被自动检查,当然,如果契约失败,程序将被粗暴地中止 。起初,你可能认为这一定是倒退 。契约不仅对处理(更不用说修复)错误毫无帮助,而且它们实际上使事情变得更糟,因为它们把每一个断言条件,无论多么良性,都变成了一个致命的错误然而,回顾前面的讨论,在处理 bug 时,首要任务是检测它们,而不是处理它们 。为此,一个导致大声崩溃的 bug(并准确地识别出哪个契约被违反)要比一个微妙的 bug 更容易被发现,这个 bug 断断续续地表现在离你可以轻易发现它的地方几百万条机器指令的下游 。
Assertions in software are in many respects like fuses in electrical circuits. Electrical engineers insert fuses in various places of their circuits to instill a controlled damage (burning a fuse) in case the circuit fails or is mishandled. Any nontrivial circuit, such as the electrical system of a car, has a multitude of differently rated fuses (a 20A fuse is appropriate for the headlights, but it’s way too big for the turn signals) to better help localize problems and to more effectively prevent expensive damage. On the other hand, a fuse can neither prevent nor fix a problem, so replacing a burned fuse doesn’t help until the root cause of the problem is removed. Just like with assertions, the main power of fuses derives from their simplicity.
软件中的断言在很多方面都像电路中的保险丝 。电子工程师在电路的各个地方安装保险丝,以便在电路发生故障或处理不当的情况下灌输一种可控的损害(熔断保险丝) 。任何非微不足道的电路,如汽车的电气系统,都有许多不同额定值的保险丝(20A 的保险丝适用于大灯,但对于转向灯来说就太大了),以更好地帮助定位问题,更有效地防止昂贵的损害 。另一方面,保险丝既不能防止也不能解决问题,所以在问题的根源被消除之前,更换熔断的保险丝并没有帮助 。就像断言一样,保险丝的主要力量来自于其简单性 。
Due to the simplicity, however, assertions are sometimes viewed as a too primitive error-checking mechanism—something that’s perhaps good enough for smaller programs, but must be replaced with a “real” error handling in the industry-strength software. This view is inconsistent with the DbC philosophy, which regards contracts (assertions in C/C++) as the integral part of the software design. Contracts embody important design decisions, namely declaring certain situations as errors rather than exceptional conditions, and, therefore, embedding them in large-scale, industry-strength software is even more important than in quick-and-dirty solutions. Imagine building a large industrial electrical circuit (say, a power plant) without fuses.
然而,由于其简单性,断言有时被认为是一种过于原始的错误检查机制--对于较小的程序来说,这种机制也许足够好,但在具有工业强度的软件中,必须用 "真正的 "错误处理来代替 。这种观点与 DbC 哲学不一致,DbC 哲学认为契约(C/C++中的断言)是软件设计的组成部分 。契约体现了重要的设计决策,即把某些情况宣布为错误,而不是异常,因此,把它们嵌入到大规模的、具有工业强度的软件中,甚至比快速和肮脏的解决方案更重要 。想象一下,在没有保险丝的情况下建造一个大型的工业电路(比如说,一个发电厂) 。

经验总结扩展阅读