1.数据引用错误
- 是否有引用的变量未赋值或未初始化?这可能是最常见的编程错误,在各种环境中都可能发生。在引用每个数据项(如变量、数组元素、结构中的域)时,应试图非正式地“证明”该数据项在当前位置具有确定的值。
- 对于所有的数组引用,是否每一个下标的值都在相应维规定的界限之内?
- 对于所有的数组引用,是否每一个下标的值都是整数?虽然在某些语言中这
不是错误,但这样做是危险的。 - 对于所有的通过指针或引用变量的引用,当前引用的内存单元是否分配?这就是所谓的 “虚调用(dangling reference)” 错误。当指针的生命期大于所引用内存单元的生命期时,错误就会发生。当指针引用了过程中的一个局部变量,而指针的值又被赋给一个输出参数或一个全局变量,过程返回(释放了引用的内存单元)结束,而后程序试图使用指针的值时,这种错误就会发生。与前面检查错误的方法类似,应试图非正式地“证明”,对于每个使用指针值的引用,引用的内存单元者都存在。
- 如果一个内存区域具有不同属性的别名,当通过别名进行引用时,内存区域中的数据值是否具有正确的属性?在 FORTRAN 语言中对 EQUIVALENCE 语句使用,或 COBOL 语言中对 REDEFINES 语句使用的地方,都可能发生这种错误。例如,一个 FORTRAN 语言程序包含一个实型变量 A 和一个整型变量 B,两者都通过使用 EQUIVALENCE 语句而成为同一内存区域的别名。如果程序先对 A 赋值,然后又引用变量 B,由于机器可能会将内存中用浮点位表示的实数当作整数,在这种情况下错误就可能发生。
- 变量值的类型或属性是否与编译器所预期的一致?当 C、C++或 COBOL 程序将某个记录读到内存中,并使用一个结构来引用它时,由于记录的物理表示与结构定义存在差异,这种情况下错误就可能发生。
- 在使用的计算机上,当内存分配的单元小于内存可寻址的单元大小时,是否存在直接或间接的寻址错误?例如,在某些条件下,定长的位串不必以字节边界为起点,但是地址又总是指向字节边界的。如果程序计算一个位串的地址,稍后又通过该地址引用这个位串,可能会指向错误的内存位置。将一个位串参数传送给一个子程序时,也可能发生这种情况。
- 当使用指针或引用变量时,被引用的内存的属性是否与编译器所预期的一致?这种错误的一个例子是,当一个指向某个数据结构的 C++指针,被赋值为另外的数据结构的地址。
- 假如一个数据结构在多个过程或子程序中被引用,那么每个过程或子程序对该结构的定义是否都相同。
- 如果字符串有索引,当对数组进行索引操作或下标引用,字符串的边界取值是否有“仅差一个(off-by-one)”的错误?
- 对于面向对象的语言,是否所有的继承需求都在实现类中得到了满足?
2.数据声明错误
- 是否所有的变量都进行了明确的声明?没有明确声明虽然不一定是错误,但通常却是麻烦的源头。举例来说,如果一个程序的子程序接收一个数组参数,却未将该参数定义为数组(如用 DIMENSION 语句),对该数组的引用(如 C=A(I))会被解释为一个函数调用,导致计算机试图将此数组当作程序执行。另外,如果某个变量在一个内部过程或程序块中没有明确声明,是否可以理解为该变量在这个程序块中被共用?
- 如果变量所有的属性在声明中没有明确说明,那么默认的属性能否被正确理解?举例来说,在 Java 语言中,程序接收到的默认属性往往是导致意外情况发生的源头。
- 如果变量在声明语句中被初始化,那么它的初始化是否正确? 在很多语言中,数组和字符串的初始化比较复杂,因此也成为容易出错的地方。
- 是否每个变量都被赋予了正确的长度和数据类型?
- 变量的初始化是否与其存储空间的类型一致?举例来说,如果 FORTRAN 语言子程序中的一个变量在每次调用子程序时都需要重新初始化一次,那么必须使用赋值语句对其初始化,而不应该用 DATA 语句。
- 是否存在着相似名称的变量(如 VOLT 和 VOLTS)?这种情况不一定是错误,但应被视为警告,这些名称可能会在程序中发生混淆。