您好,欢迎访问三七文档
[本文部分内容和例子都来自于PC-Lint用户手册,翻译得时候加上了点自己的理解]摘要:C/C++语言的语法拥有其它语言所没有的灵活性,这种灵活性带来了代码效率的提升,但相应增加了代码中存在隐患的可能性。静态代码检查工具PC-Lint则偏重于代码的逻辑分析,它能够发现代码中潜在的错误,比如数组访问越界、内存泄漏、使用未初始化变量等。本文将介绍如何安装和配置PC-Lint代码检查工具以及如何将PC-Lint与常见的代码编辑软件集成。关键词:代码检查PC-Lint规则选项目录摘要1引言2PC-Lint介绍3PC-Lint的代码检查功能3.1强类型检查3.2变量值跟踪3.3赋值顺序检查3.4弱定义检查3.5格式检查3.6缩进检查3.7const变量检查3.8volatile变量检查4PC-Lint软件使用方法4.1安装与配置4.2PC-Lint与常用开发工具的集成(VisualC++,SourceInsight,UEdit)5总结参考文献附录一PC-Lint重要文件说明附录二错误信息禁止选项说明附录三PC-Lint检测中的常见错误一引言C/C++语言的语法拥有其它语言所没有的灵活性,这种灵活性带来了代码效率的提升,但相应也使得代码编写具有很大的随意性,另外C/C++编译器不进行强制类型检查,也不做任何边界检查,这就增加了代码中存在隐患的可能性。如果能够在代码提交测试之前发现这些潜在的错误,就能够极大地减轻测试人员的压力,减少软件项目的除错成本,可是传统的C/C++编译器对此已经无能为力,这个任务只能由专用的代码检查工具完成。目前有很多C/C++静态代码检查工具,其中LogiscopeRuleChecker和PC-Lint是目前应用比较广泛的两个工具。这两个检查工具各有特色,LogiscopeRuleChecker倾向于代码编码规范的检查,比如代码缩进格式、case语句书写规范、函数声明和布尔表达式的编写规则等,而PC-Lint则偏重于代码的逻辑分析,它能够发现代码中潜在的错误,比如数组访问越界、内存泄漏、使用未初始化变量等。本文将介绍如何安装和配置PC-Lint代码检查工具以及将PC-Lint与常见的代码编辑软件,如VisualC++,SourceInsight集成的方法,同时还将简要介绍一些PC-Lint常用的代码检查选项。二PC-Lint介绍PC-Lint是GIMPELSOFTWARE公司开发的C/C++软件代码静态分析工具,它的全称是PC-Lint/FlexeLintforC/C++,PC-Lint能够在Windows、MS-DOS和OS/2平台上使用,以二进制可执行文件的形式发布,而FlexeLint运行于其它平台,以源代码的形式发布。PC-lint在全球拥有广泛的客户群,许多大型的软件开发组织都把PC-Lint检查作为代码走查的第一道工序。PC-Lint不仅能够对程序进行全局分析,识别没有被适当检验的数组下标,报告未被初始化的变量,警告使用空指针以及冗余的代码,还能够有效地帮你提出许多程序在空间利用、运行效率上的改进点。通过下面的例子就可以看出PC-Lint工具的强大功能:1:2:char*report(intm,intn,char*p)3:{4:intresult;5:char*temp;6:longnm;7:inti,k,kk;8:charname[11]=JoeJakeson;9:10:nm=n*m;11:temp=p==?null:p;12:for(i=0;im;I++){14:k++;15:kk=i;16:}17:18:if(k==1)result=nm;19:elseif(kk0)result=1;20:elseif(kk0)result=-1;21:22:if(m==result)return(temp);23:elsereturn(name);24:}这是一段C代码,可以通过大多数常见的C语言编译器的检查,但是PC-Lint能够发现其中的错误和潜在的问题:第8行向name数组赋值时丢掉了结尾的nul字符,第10行的乘法精度会失准,即使考虑到long比int的字长更长,由于符号位的原因仍然会造成精度失准,第11行的比较有问题,第14行的变量k没有初始化,第15行的kk可能没有被初始化,第22行的result也有可能没有被初始化,第23行返回的是一个局部对象的地址。随着C++语言的出现,C/C++编译器有了更严格的语法检查,但是仍然不能避免出现有BUG的程序。C++的类型检查依然不如Pascal那么严格。对于一个小程序,多数程序员都能够及时发现上面出现的错误,但是从一个拥有成千上万行代码的大型软件中找出这些瑕疵将是一项烦琐的工作,而且没有人可以保证能找出所有的这类问题。如果使用PC-Lint,只需通过一次简单的编译就可以检查出这些错误,这将节省了大量的开发时间。从某种意义上说。PC-Lint是一种更加严格的编译器,它除了可以检查出一般的语法错误外,还可以检查出那些虽然符合语法要求,但很可能是潜在的、不易发现的错误。三PC-Lint的代码检查功能PC-Lint能够检查出很多语法错误和语法上正确的逻辑错误,PC-Lint为大部分错误消息都分配了一个错误号,编号小于1000的错误号是分配给C语言的,编号大于1000的错误号则用来说明C++的错误消息。表1列出了PC-Lint告警消息的详细分类:以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级:表1列出了PC-Lint告警消息分类错误说明CC++告警级别语法错误1-1991001-11991内部错误200-2990致命错误300-3990告警400-6991400-16992消息700-8001700-18993可选信息900-9991900-19994-wlib(0)不生成任何库信息-wlib(1)只生成错误信息(当处理库的源代码时)-wlib(2)生成错误和告警信息-wlib(3)生成错误、告警和其它信息(这是默认设置)-wlib(4)产生所有信息PC-Lint的检查分很多种类,有强类型检查、变量值跟踪、语义信息、赋值顺序检查、弱定义检查、格式检查、缩进检查、const变量检查和volatile变量检查等等。对每一种检查类型,PC-Lint都有很多详细的选项,用以控制PC-Lint的检查效果。PC-Lint的选项有300多种,这些选项可以放在注释中(以注释的形式插入代码中),例如:/*lintoption1option2...optionalcommentary*/选项可以有多行//lintoption1option2...optionalcommentary选项仅为一行(适用于C++)选项间要以空格分开,lint命令一定要小写,并且紧跟在/*或//后面,不能有空格。如果选项由类似于操作符和操作数的部分组成,例如-esym(534,printf,scanf,operatornew),其中昀后一个选项是operatornew,那么在operator和new中间只能有一个空格。PC-Lint的选项还可以放在宏定义中,当宏被展开时选项才生效。例如:#defineDIVZERO(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中列出:表2强类型检查strong选项和参数表A对强类型变量赋值时进行类型检查,这些赋值语句包括:直接赋值、返回值、参数传递、初始化。A参数后面可以跟以下字符,用来弱化A的检查强度:i忽略初始化r忽略Return语句p忽略参数传递a忽略赋值操作c忽略将常量赋值(包括整数常量、常量字符串等)给强类型的情况z忽略Zero赋值,Zero定义为任何非强制转换为强类型的0常量。例如:0L和(int)0都是Zero,这些选项字符的顺序对功能没有影响。但是A和J选项的弱化字符必须紧跟在它们之后。B选项和b选项不能同时使用,f选项必须搭配B选项或b选项使用,如果不指定这些选项,-strong的作仅仅声明type为强类型而不作任何检查。下面用一段代码演示-strong选项的用法:用就是但是(HANDLE)0当HANDLE是一个强类型的时候就不是Zero。(HANDLE*)0也不是例如使用-strong(Ai,BITS)设置,PC-Lint将会对从非BITS类型数据向BITS类型数据赋值的代码发出告警,但是忽略变量初始化时的此类赋值。X当把强类型的变量赋指给其他变量的时候进行类型检查。弱化参数i,r,p,a,c,z同样适用于X并起相同的作用。J选项是当强类型与其它类型进行如下的二进制操作时进行检查,下面是J的参数:e忽略==、!=和?:操作符r忽略、=、和=o忽略+、-、*、/、%、|、&和^c忽略该强类型与常量进行以上操作时的检查z忽略该强类型与Zero进行以上操作时的检查使用忽略意味着不会产生告警信息。举个例子,如果Meters是个强类型,那么它只在判断相等和其他关系操作时才会被正确地检查,其它情况则不检查,在这个例子中使用J选项是正确的。BB选项有两个效果:1.出于强类型检查的目的,假设所有的Boolean操作返回一个和Type兼容的类型,所谓Boolean操作就是那些指示结果为true或false的操作,包括前面提到的四种关系运算符和两种等于判断符,取反操作符!,二元操作符&&和||。2.在所有需要判断Bolean值的地方,如if语句和while语句,都要检查结果是否符合这个强类型,否则告警。例如if(a)...当a为int时,将产生告警,因为int与Bolean类不兼容,所以必须改为if(a!=0)。b仅仅假定每一个Bolean类操作符都将返回一个与Type类型兼容的返回值。与B选项相比,b选项的限制比较宽松。l库标志,当强类型的值作为参数传递给库函数等情况下,不产生告警。f与B或b连用,表示抑止对1bit长度的位域是Boolean类型的假定,如果不选该项表示1bit长度的位域被缺省假定为Boolean类型。//lint-strong(Ab,Bool)选项是以注释的形式插入代码中ty
本文标题:pc_lint经验
链接地址:https://www.777doc.com/doc-4010912 .html