断言(软件开发)
目录
断言(软件开发)简介
在计算机编程中,特别是在使用命令式编程范式时,断言是一个与程序中的某一点相连的谓词(状态空间上的布尔值函数,通常用程序的变量表示为逻辑命题),在代码执行的那一点上总是应该评估为真。断言可以帮助程序员阅读代码,帮助编译器编译代码,或者帮助程序检测自身的缺陷。对于后者,一些程序通过在运行时实际评估谓词来检查断言。然后,如果它实际上不是真的–断言失败–程序就认为自己有缺陷,通常会故意崩溃或抛出一个断言失败的异常。下面的代码包含两个断言,x>0和x>1,它们在执行过程中的指定点确实是真的。x=1;assertx>0;x++;assertx>1。程序员可以使用断言来帮助指定程序和推理程序的正确性。例如,一个前提条件–放在一段代码的开头的断言–确定了程序员期望代码执行的状态集。放在结尾的后置条件描述了执行结束后的预期状态。例如:x>0{x++}x>1.上面的例子使用了C.A.R.Hoare在1969年的文章中使用的包括断言的符号。这种符号不能在现有的主流编程语言中使用。然而,程序员可以使用其编程语言的注释功能包括未检查的断言。例如,在C语言中。x=5;x=x+1;//{x>1}。注释中包含的大括号有助于将这种注释的使用与其他使用区分开来。库也可以提供断言功能。例如,在C语言中使用支持C99的glibc。#include<assert.hintf(void){intx=5;x=x+1;assert(x>1);}一些现代编程语言包括检查过的断言–在运行时或有时静态地检查的语句。如果一个断言在运行时被评估为错误,就会导致断言失败,这通常会导致执行中止。这引起了人们对检测到的逻辑不一致的位置的注意,这可能比其他情况下产生的行为要好。断言的使用有助于程序员设计、开发和推理程序。
使用方法
在Eiffel等语言中,断言是设计过程的一部分;其他语言,如C和Java,只在运行时使用它们来检查假设。在这两种情况下,它们都可以在运行时检查其有效性,但通常也可以被压制。
契约设计中的断言
断言可以作为一种文档形式发挥作用:它们可以描述代码在运行前期望找到的状态(其前提条件),以及代码在运行结束后期望得到的状态(后置条件);它们还可以指定类的不变性。Eiffel将这种断言集成到语言中,并自动提取它们来记录类。这构成了契约设计方法的一个重要部分。这种方法在没有明确支持的语言中也很有用:使用断言语句而不是注释中的断言的好处是,程序可以在每次运行时检查断言;如果断言不再成立,可以报告错误。这可以防止代码与断言不同步。
用于运行时检查的断言
断言可用于验证程序员在实现程序时做出的假设在程序被执行时仍然有效。例如,考虑下面的Java代码。inttotal=countNumberOfUsers();if(total%2==0){//totaliseven}else{//totalisoddandnon-negativeasserttotal%2==1;}在Java中,%是余数运算符(modulo),在Java中,如果它的xxx个操作数是负数,结果也可以是负数(与数学中使用的modulo不同)。

在这里,程序员假设total是非负的,所以除以2的余数总是0或1。该断言明确了这一假设:如果countNumberOfUsers确实返回一个负值,那么程序可能有一个错误。这种技术的一个主要优点是,当错误确实发生时,可以立即直接检测出来,而不是在以后通过通常不明显的影响来检测。由于断言失败通常会报告代码的位置,人们通常可以准确地指出错误,而不需要进一步调试。断言有时也被放置在执行不应该到达的地方。例如,在C、C++和Java等语言中,断言可以放在switch语句的默认子句处。任何程序员没有故意处理的情况都会引发错误,程序会中止,而不是在错误的状态下默默地继续。