《3、PC-Lint的代码检查功能》
PC-Lint能够检查出很多语法错误和语法上正确的逻辑错误,PC-Lint为大部分错误消息都分配了一个错误号,编号小于1000的错误号是分配给C 语言的,编号大于1000的错误号则用来说明C++的错误消息。表 1 列出了PC-Lint告警消息的详细分类:
错误说明 | C | C++ | 告警级别 |
语法错误 | 1-199 | 1001-1199 | 1 |
内部错误 | 200-299 | 0 | |
致命错误 | 300-399 | 0 | |
告警 | 400-699 | 1400-1699 | 2 |
消息 | 700-800 | 1700-1899 | 3 |
可选信息 | 900-999 | 1900-1999 | 4 |
以C 语言为例,其中的编号1-199指的是一般编译器也会产生的语法错误;编号200-299是PC-Lint程序内部的错误,这类错误不会出现在代码中的;编号300-399指的是由于内存限制等导致的系统致命错误。编号400-999中出现的提示信息,是根据隐藏代码问题的可能性进行分类的:其中编号 400-699指的是被检查代码中很可能存在问题而产生的告警信息;编号700-899中出现的信息,产生错误的可能性相比告警信息来说级别要低,但仍然可能是因为代码问题导致的问题。编号900-999是可选信息,他们不会被默认检查,除非你在选项中指定检查他们。
PC-Lint/FelexLint提供了和许多编译器类似的告警级别设置选项-wLevel,它的告警级别分为以下几个级别,缺省告警级别为3级:
-w0 不产生信息(除了遇到致命的错误)
-w1 只生成错误信息 -- 没有告警信息和其它提示信息
-w2 只有错误和告警信息
-w3 生成错误、告警和其它提示信息(这是默认设置)
-w4 生成所有信息
PC-Lint/FelexLint还提供了用于处理函数库的头文件的告警级别设置选项-wlib(Level),这个选项不会影响处理C/C++源代码模块的告警级别。它有和-wLevel相同的告警级别,缺省告警级别为3级:
-wlib(0) 不生成任何库信息
-wlib(1) 只生成错误信息(当处理库的源代码时)
-wlib(2) 生成错误和告警信息
-wlib(3) 生成错误、告警和其它信息(这是默认设置)
-wlib(4) 产生所有信息
PC-Lint的检查分很多种类,有强类型检查、变量值跟踪、语义信息、赋值顺序检查、弱定义检查、格式检查、缩进检查、const变量检查和 volatile变量检查等等。对每一种检查类型,PC-Lint都有很多详细的选项,用以控制PC-Lint的检查效果。PC-Lint的选项有300 多种,这些选项可以放在注释中(以注释的形式插入代码中),例如:
/*lint option1 option2 ... optional commentary */ 选项可以有多行
//lint option1 option2 ... optional commentary 选项仅为一行(适用于C++)
选项间要以空格分开,lint命令一定要小写,并且紧跟在/*或//后面,不能有空格。如果选项由类似于操作符和操作数的部分组成,例如-esym (534, printf, scanf, operator new),其中最后一个选项是operator new,那么在operator和new中间只能有一个空格。PC-Lint的选项还可以放在宏定义中,当宏被展开时选项才生效。例如:
#define DIVZERO(x) /*lint -save -e54 */ ((x) /0) /*lint -restore */ 允许除数为0而不告警
下面将分别介绍PC-Lint常用的,也是比较重要的代码检查类型,并举例介绍了各个检查类型下可能出现的告警信息以及常用选项的用法:
3.1 强类型检查
强类型检查选项“-strong”和它的辅助(补充)选项“-index”可以对typedef定义的数据类型进行强类型检查,以保证只有相同类型之间的变量才能互相赋值,强类型检查选项strong的用法是:
-strong( flags[, name] ... )
strong选项必须在typedef定义类型之前打开,否则PC-Lint就不能识别typedef定义的数据类型,类型检查就会失效。flags参数可以是A、J、X、B、b、l和f,相应的解释和弱化字符在表 2 中列出:
A | 对强类型变量赋值时进行类型检查,这些赋值语句包括:直接赋值、返回值、参数传递、初始化 。 A参数后面可以跟以下字符,用来弱化A的检查强度: i 忽略初始化 r 忽略Return语句 p 忽略参数传递 a 忽略赋值操作 c 忽略将常量赋值(包括整数常量、常量字符串等)给强类型的情况 z 忽略Zero赋值,Zero定义为任何非强制转换为强类型的0常量。例如:0L和(int)0都是Zero, 但是(HANDLE)0当HANDLE是一个强类型的时候就不是Zero。(HANDLE *)0也不是例如使用-strong(Ai,BITS)设置,PC-Lint将会对从非BITS类型数据向BITS类型数据赋值的代码发出告警,但是忽略变量初始化时的此类赋值。 |
X | 当把强类型的变量赋指给其他变量的时候进行类型检查。弱化参数i, r, p, a, c, z同样适用于X并起相同的作用。 |
J | 选项是当强类型与其它类型进行如下的二进制操作时进行检查,下面是J的参数: 使用忽略意味着不会产生告警信息。举个例子,如果Meters是个强类型,那么它只在判断相等和其他关系操作时才会被正确地检查,其它情况则不检查,在这个例子中使用J选项是正确的。 |
B | B选项有两个效果: 1. 出于强类型检查的目的,假设所有的Boolean操作返回一个和Type兼容的类型,所谓Boolean操作就是那些指示结果为true或false的操作,包括前面提到的四种关系运算符和两种等于判断符,取反操作符!,二元操作符&&和||。 2. 在所有需要判断Bolean值的地方,如if语句和while语句,都要检查结果是否符合这个强类型,否则告警。 例如if(a)...当a为int时,将产生告警,因为int与Bolean类不兼容ÿ |