代码走查工具PCLint课件_第1页
代码走查工具PCLint课件_第2页
代码走查工具PCLint课件_第3页
代码走查工具PCLint课件_第4页
代码走查工具PCLint课件_第5页
已阅读5页,还剩137页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

代码走查工具PCLint代码走查工具PCLint1目录PC-Lint简介PC-Lint基本使用方法PC-Lint常用选项PC-Lint在各种环境中的集成PC-Lint常见告警分析及解决措施目录PC-Lint简介2代码走查工具PCLint课件3代码走查工具PCLint课件4PC-Lint基本使用方法PC-Lint是一个命令行工具,因此使用方式是命令行带参数方式使用。一般的使用格式为: lint-nt.exe[Option]file1file2…如:lint-nt.exe-u-id:\lintstd.lntsample.c在这里-u表示只对本单元进行检查-id:\lint是表示会在d:\lint目录下搜索文件std.lnt是表示要使用的配置文件sample.c表示要检查的源文件PC-Lint基本使用方法PC-Lint是一个命令行工具,因5PC-Lint基本使用方法检查一个目录下的所有源文件可以使用以下方法:如:lint-nt.exe-u-id:\lintstd.lntd:\osp\vos\*.cpp跟前面不同的是这里将sample.c变成了d:\osp\vos\*.cpp,使用*.cpp的意思是它会检查d:\osp\vos目录下的所有.cpp文件,但是它不能检查子目录下的文件PC-Lint基本使用方法检查一个目录下的所有源文件可以使用6PC-Lint基本使用方法要检查所有包括子目录的文件可以使用以下方法: lint-nt-id:\lintstd.lntAllSource.lnt在AllSource.lnt文件中可以放置如下:Moudule1-Dir\*.cpp Moudule2-Dir\*.cpp Moudule3-Dir\*.cpp...当检查所有文件时不需要使用-u选项PC-Lint基本使用方法要检查所有包括子目录的文件可以使用7PC-Lint基本使用方法PC-Lint配置文件介绍PC-Lint使用那个配置文件是由命令行参数决定的,一般地都使用std.lnt文件,std.lnt文件中可以包含各种配置选项,还可以包含其他的配置文件,有点类似C的头文件,里面可以include许多其他头文件,不过PC-Lint配置文件包含其他配置文件不需要写include,直接写文件名就可以了。每个配置文件里都可以包含配置选项,这些配置选项也可以放在命令行中,一般为使用方便,命令行中不要放很多选项,尽量都将选项放到配置文件中PC-Lint基本使用方法PC-Lint配置文件介绍8PC-Lint基本使用方法以下是VC下的配置文件样例//Microtec32-bit,-si4-sp4,lib-w32.lnt//Standardlintoptionsco-msc60.lnt//PC-Lint提供的对VC6的告警屏蔽文件lib-w32.lnt//PC-Lint提供的对VC6库头文件的告警屏蔽文件options.lnt-si4-sp4//用户自定义的选项文件env-vc6.lnt//用户用来设置编辑环境的配置文件-id:\vc6\vc98\include//include目录-id:\vc6\vc98\mfc\include//include目录PC-Lint基本使用方法以下是VC下的配置文件样例9PC-Lint基本使用方法一般来说,PC-Lint经常会有一些误报,为了消除这些误报,不得不将程序风格改动来规避,但有时候怎么改写程序都有告警,比如说你定义了两个宏,前面那个宏里有一半大括号{,后面那个宏里有另一半大括号},这时候一定会有告警,你不得不使用一些PC-Lint选项来屏蔽这些告警。一般情况下,我们都将自己要写的选项放在Options.lnt文件中PC-Lint基本使用方法一般来说,PC-Lint经常会有一10PC-Lint基本使用方法另外还有关于编辑环境的问题,如果把PC-Lint集成到某个编辑环境中,那么他输入的格式必须和对应环境吻合才能保证在鼠标点击(或双击)错误消息条目时可以自动定位到对应源代码行,一般来说这类配置都放置在env-xxx.lnt文件中,如VC6的时env-vc6.lnt,SourceInsight的是env-si.lntPC-Lint本身提供了对各种编译器及对应库头文件的告警屏蔽文件,如co-msc60.lnt是对vc6的,lib-w32.lnt是对Win32库头文件告警的屏蔽配置文件PC-Lint基本使用方法另外还有关于编辑环境的问题,如果把11PC-Lint常用选项-i选项这个选项主要是用来设置include路径的如:-iD:\VC6\VC98\Include-e#选项这个选项主要是用来屏蔽告警号为#的告警如:-e818表示不显示告警号为818的告警-esym(#,符号名)选项这个选项主要是用来屏蔽告警号为#的某个符号的告警,如-esym(39,std)-emacro(#,宏名称)选项这个选项主要是用来屏蔽告警号为#的某个宏的告警PC-Lint常用选项-i选项12PC-Lint常用选项-dname[=value]这个选项主要是用来定义一个宏的如:-dWIN32,-dalpha=0-sp#表示指针的尺寸大小是#字节如:-sp4表示指针是4个字节大小-si#表示int的尺寸大小是字节如:-si4表示int型是4个字节大小-t#设置Tab键的大小为#个空格,缺省是8PC-Lint常用选项-dname[=value]13PC-Lint常用选项-sem选项这个选项主要是用来消除一些语义上的告警 比如说在一个函数A里面分配了内存,这时调用了另一个函数AddNode将分配的内存保存起来了,因此在函数A里面没有释放内存,如果使用PC-Lint检查会有内存泄漏方面的告警,因为PC-Lint不知道函数AddNode将分配的内存保存起来了,要消除这个告警就要用到-sem选项了。假设AddNode的第2个参数是用来保存分配内存,用法如下 -sem(AddNode,custodial(2)) 这里custodial关键字是表示保存的意思,2是表示第2个参数。 -sem选项还有些其他用法,大家可以看PC-Lint自带的pc-lint.pdf文件,里面有详细的解析PC-Lint常用选项-sem选项14PC-Lint常用选项-function(function0,function1,…)选项 这个选项一般情况下主要是用来表示function1及后面省略掉的函数和function0有类似的行为。 如:-function(malloc,mymalloc1,mymalloc2)表示mymalloc1,mymalloc2和malloc有类似的行为,因为malloc是用来分配内存的,所以pc-lint在检查mymalloc1和mymalloc2时也会想检查malloc一样看是否有释放掉 象上一页里已经定义了AddNode为保存内存的函数,如果碰到还有一个函数AddEvent也是有保存内存的功能,我们除了可以使用-sem(AddEvent,custodial(2))外,也可以使用-function(AddNode,AddEvent),效果是一样的。不过要注意的是AddEvent保存内存的参数也要和AddNode一样是第2个。PC-Lint常用选项-function(function015PC-Lint常用选项-format选项 这个选项主要是用来设置输出告警消息格式的,以便于可以和编辑环境格式一样,便于自动定位到告警对应的源代码 如对SourceInsight,-format选项的使用如下:-"format=%f%l%t%n:%m“这里%f表示文件名%l表示代码行号%t表示告警类型,如warning,error等%n表示PC-Lint的告警号%m表示PC-Lint输出的告警文本信息PC-Lint常用选项-format选项16PC-Lint常用选项-fallthrough 这个选项主要是用在switchcase中没有使用break的情况 可以在代码中使用//lint–fallthrough来消除没有使用break的告警-save 保存错误抑制状态 如:在代码中使用//lint–save–e429则表示从这行开始之后的代码抑制429告警的出现,直到使用//lint–restore来进行恢复后才会重新出现429告警-restore 重新设置错误抑制状态,使用-save选项抑制的告警将重新恢复,在使用了-save选项后一定要记住使用-restore进行恢复,否则可能有许多告警就被屏蔽调不出现了。PC-Lint常用选项-fallthrough17PC-Lint常用选项其他一些常用选项还有-elib抑制库头文件的告警-elibsym抑制库头文件中某个符号的告警-wlevel设置告警级别-efile用来抑制一个或多个文件里的告警-efunc用来抑制一个或多个函数里的告警+rw设置保留关键字等等。象-efile,-wlevel这些告警不要轻易使用这些选项的具体用法请看pc-lint.pdf文件PC-Lint常用选项其他一些常用选项还有18PC-Lint在各种环境中的集成PC-Lint在各种环境中的集成方法原理都是一样的,只要掌握前面讲的基本用法,知道如何用命令行来检测单个文件,一个目录下的所有文件,许多目录下的所有文件等,然后再结合各种环境的具体设置,就可以很方便地将PC-Lint集成到各种应用环境中了。下面将以VC6,SourceInsight,UltraEdit,Tornado四种环境为例讲述如何集成PC-LintPC-Lint在各种环境中的集成PC-Lint在各种环境中的19PC-Lint在各种环境中的集成在vc环境中集成在VC的Tools菜单中,按Customize…会出现下一页出现的对话框先在上面的列表框里增加一个条目,里面填上PC-Lint80,文本内容可以是其他的,由你自己决定。然后在Command:这一栏中输入PC-Lint的执行文件名,要带上目录再在Arguments:一栏里填上 -u-iC:\Lintstd.lnt$(FileName) 这里$(FileName)表示VC窗口里当前打开的文件名 你也可以将它改成$(FileDir)\*.cpp表示检查当前打开文件同一目录下的所有.cpp文件,通常用于检查一个模块 还可以改成AllSource.lnt,象前面讲过的一样,AllSource.lnt是一个放置有所有文件的配置文件,这时要将-u去掉。PC-Lint在各种环境中的集成在vc环境中集成20PC-Lint在各种环境中的集成PC-Lint在各种环境中的集成21PC-Lint在各种环境中的集成再在InitialDirectory一栏里填上$(FileDir) 最后再将useoutputwindow打上勾就完成了将PC-Lint集成到VC环境中PC-Lint在各种环境中的集成再在InitialDire22PC-Lint在各种环境中的集成在SourceInsight3.1中的集成在SourceInsight3.1中集成PC-Lint过程如下: 1)从Options菜单中选择“CustomCommands”命令项。 2)点Add键会出现下面的AddNewCustomCommand对话框在Newcommandname:栏中输入“PC-lint80”,原则上这个名称可以随便起,只要你能搞清楚它的含义就可以了,然后按OK按钮。

PC-Lint在各种环境中的集成在SourceInsight23PC-Lint在各种环境中的集成 3)在Run栏中输入“d:\lint\lint-nt-u-ic:\lintstd.lntenv-si%f”其中d:\lint是你PC-LINT的安装目录,%f是表示当前打开的文件。如果要Lint多个文件则需要使用配置文件,在配置文件里包含多个文件,将%f改成你自己的配置文件即可。 4)在Output栏中选择“IconicWindow”、“CaptureOutput”。 5)在Control栏中选择“SaveFilesFirst”、将缺省打了勾选上的“PauseWhenDone”改成不选择。 6)在SourceLinksinOutput栏中选择“ParseLinksinOutput”、“File,thenLine”。 7)在Pattern栏中将缺省设置改成^\([^]*\)\([0-9]+\)就大功告成了。 8)如果需要Lint当前打开文件的同一目录下所有文件,可以将%f改成%d\*.cpp 如下图:PC-Lint在各种环境中的集成 3)在Run栏中输入“d:24PC-Lint在各种环境中的集成PC-Lint在各种环境中的集成25PC-Lint在各种环境中的集成在Tornado2.0环境中集成在Tornado2.0的Tools菜单中点Customize…后会出现如下一页的对话框。先在对话框中按Add…按钮在MenuText一栏中输入PC-Lint80在ToolCommand:一栏中输入D:\LINT\lint-nt.exe-iD:\Lintstd.lnt$filename你也可以象前面讲过VC中集成一样,将$filename改成$filedir\*.cpp或AllSource.lnt在Working一栏中输入$filedir再将RedirecttoChildWind选上,按OK就可以了PC-Lint在各种环境中的集成在Tornado2.0环境中26PC-Lint在各种环境中的集成PC-Lint在各种环境中的集成27PC-Lint在各种环境中的集成在UltraEdit环境中集成在Advanced菜单中选ToolConfiguration...,显示图如下一页所示在commandline:中填写: d:\lint\lint-nt–iD:\Lintstd.lnt%F在MenuItem中填写:PC-Lint80在CommandOutput中选择:(x)OutputtoListBox和(x)CaptureOutput5)按Insert按钮再按OK按钮就可以了PC-Lint在各种环境中的集成在UltraEdit环境中集28PC-Lint在各种环境中的集成PC-Lint在各种环境中的集成29PC-Lint常见告警分析及解决措施PC-Lint的告警级别定义如下:PC-Lint常见告警分析及解决措施PC-Lint的告警级别30PC-Lint常见告警分析及解决措施PC-Lint告警分为0~4级,其中0级是内部错误或致命错误,1级告警是句法错误,2级告警是警告,3级是信息,4级是可选的,4级缺省是不打开的。0级告警是不允许出现的,1级告警一般也是不允许出现的,如果出现,说明可能PC-Lint配置上可能有问题,或者程序根本编译不过,2级告警一般也是不能屏蔽的,2级告警很多是内存资源没有释放,指针越界一类的警告,会产生严重问题,3级告警有些告警也是非常重要的,会引起严重问题,有些告警属于提示信息,问题不是很大,所以3级告警里要分情况对待。0~2级告警都不能使用-e选项进行屏蔽,只能使用-esym,-emacro,-sem之类的选项进行屏蔽;3级告警要根据具体情况,有些可以使用-e选项进行屏蔽,有些不可以。下面就对经常遇到的一些告警进行详细的分析及讨论解决措施。PC-Lint常见告警分析及解决措施PC-Lint告警分为031PC-Lint常见告警分析及解决措施告警号:39

告警等级:1告警消息样例: stl_type_traits.h(279):error39:(Error--Redefinitionofsymbol'__type_traits<constsignedchar*>'conflictswithline271)分析及解决措施:

可以使用-esym(39,符号名)来消除此告警,在这里可以使用

-esym(39,__type_traits<constsignedchar*>PC-Lint常见告警分析及解决措施告警号:39告警等32PC-Lint常见告警分析及解决措施告警号:402

告警等级:2告警消息样例: XXX.cpp(77):error402:(Warning--staticfunction'VOS_GetFixedStackDepth(void)'(line77)分析及解决措施:

主要是函数原型申明为静态的,但函数实体确漏写了static造成PC-Lint常见告警分析及解决措施告警号:402告警33PC-Lint常见告警分析及解决措施告警号:413

告警等级:2告警消息样例: xxx.cpp(1118):error413:(Warning--Likelyuseofnullpointerunknown-name'inargumenttooperatorunary*分析及解决措施:

指针未校验引起,如果确认指针可以由外部保证则可以使用ASSERT来消除此告警PC-Lint常见告警分析及解决措施告警号:413告警34PC-Lint常见告警分析及解决措施告警号:429

告警等级:2告警消息样例: XXX.cpp(2474):error429:(Warning--Custodialpointer'pEvent'(line2459)hasnotbeenfreedorreturned)分析及解决措施: AddEvent将指针pEvent保存起来,解决办法是使用 -sem(ISystem::AddEvent,1p,custodial(1))来屏蔽此告警,这里1p是表示第1个参数,custodial(1)是表示第1个参数被保留起来了。 另外还有函数递归调用时,如果递归调用时使用的参数和函数参数同名也会出现此告警,递归调用时必须将参数改名。还有一种情况是在父函数里分配了内存,传递到子函数后,由于子函数里有return语句有时也会产生429告警,这种行为非常奇怪,目前没有找到好的消除办法,尽量将程序结构改成把return语句去掉就没有这个告警了。PC-Lint常见告警分析及解决措施告警号:429告警35PC-Lint常见告警分析及解决措施告警号:522

告警等级:2告警消息样例: error522:(Warning--Expectedvoidtype,assignment,incrementordecrement)分析及解决措施:

单独的*p++型可以改写成(*p)++可以避免此告警,如果是*(p++)就没有必要了,直接写成p++就可以了。*p++型作为右值的话一般不会有此告警,另外函数返回值未处理有时也有此告警PC-Lint常见告警分析及解决措施告警号:522告警36PC-Lint常见告警分析及解决措施告警号:525

告警等级:2告警消息样例:

Warning525:Negativeindentationfromline312分析及解决措施:

如果确定程序没有问题的话,可以检查告警525的产生是否由于程序中有Tab键或者程序排版没有对齐造成的,将Tab删掉,改成空格,将排版格式对齐就可以了PC-Lint常见告警分析及解决措施告警号:525告警37PC-Lint常见告警分析及解决措施告警号:534

告警等级:2告警消息样例:

xxx.cpp(1694):error534:(Warning--Ignoringreturnvalueoffunction‘YYY(unsignedlong)'(comparewithline180分析及解决措施:

一般都是由于没有处理函数返回值造成,如果确信函数返回值可以不处理的话,只要在不需要处理函数返回值的函数前加上(void)就可以了。PC-Lint常见告警分析及解决措施告警号:534告警38PC-Lint常见告警分析及解决措施告警号:539

告警等级:2告警消息样例: Warning539:Didnotexpectpositiveindentationfromline210分析及解决措施:

除了左边所说的问题外,如果程序中有TAB键,且不是8个空格的话,有时也会引起告警539的产生,如果消除掉左边所说的问题还有539告警的话,则估计是由于程序中有Tab键造成的,将Tab删掉,改成空格,并且排版格式要对齐就可以了。PC-Lint常见告警分析及解决措施告警号:539告警39PC-Lint常见告警分析及解决措施告警号:613

告警等级:2告警消息样例: XXX.cpp(374):error613:(Warning--Possibleuseofnullpointer'matrix'inleftargumenttooperator'ptr+int'分析及解决措施:

通常是由于指针和整数相加造成的问题bool*matrix=(bool*)newbool[(size_t)(len*len)];bool*dep=matrix+row*len;可以改写成先将地址转换成整数形式,再相加后,再将整数形式的地址转换为指针可以消除此告警。另外还有指针在其他函数校验了,但在本函数内没有校验也会有此告警,象组建中,因为有Initialize()函数里保证那些组件指针的合法性,因此在其他函数里不再需要对这些指针做校验,此种情况可以使用ASSERT()来消除此告警,其他情况请使用指针校验来消除此告警。PC-Lint常见告警分析及解决措施告警号:613告警40PC-Lint常见告警分析及解决措施告警号:616

告警等级:2告警消息样例: XXX.cpp(162):error616:(Warning--controlflowsintocase/default)分析及解决措施:

case没有break;语句的问题, 使用//lint-fallthrough来屏蔽PC-Lint常见告警分析及解决措施告警号:616告警41PC-Lint常见告警分析及解决措施告警号:661

告警等级:2告警消息样例: XXX.cpp(2560):error661:(Warning--Possibleaccessofout-of-boundspointer(1beyondendofdata)byoperator'unary*‘分析及解决措施:

内存越界问题,如果由调用方保证,可以使用ASSERT来消除此告警,否则应该对输入参数进行校验PC-Lint常见告警分析及解决措施告警号:661告警42PC-Lint常见告警分析及解决措施告警号:668

告警等级:2告警消息样例: XXX.cpp(1211):error668:(Warning--Possiblypassinganullpointertofunction'memset(void*,int,unsignedint)',arg.no.1分析及解决措施:

指针可能为null,一般都是由于没有进行校验引起,如果指针由外部可以保证的话,可以使用ASSERT消除这个告警PC-Lint常见告警分析及解决措施告警号:668告警等43PC-Lint常见告警分析及解决措施告警号:672

告警等级:2告警消息样例: XXX.cpp(353):error672:(Warning--Possiblememoryleakinassignmenttopointer'cmpFactory::m_pLibrary')分析及解决措施:

一个函数中申请了内存在本函数中没有释放,在其他函数中释放会引起这个告警可以使用-esym或-sem来消除PC-Lint常见告警分析及解决措施告警号:672告警44PC-Lint常见告警分析及解决措施告警号:685

告警等级:2告警消息样例: XXX.cpp(2346):error685:(Warning--Relationaloperator'<='alwaysevaluatesto'true')分析及解决措施:

简单问题,通常是代码里判断条件错误造成,修改代码即可比如定义一个char类型变量,条件判断让它<=127,那么显然判断总是真PC-Lint常见告警分析及解决措施告警号:685告警45PC-Lint常见告警分析及解决措施告警号:708

告警等级:2告警消息样例: XXX.cpp(1470):error708:(Info--unioninitialization)分析及解决措施:

要对联合体的第一个成员赋值进行初始化才不会告警不可以直接写成unionAa={0};而应该写成unionAa;a.First=0;PC-Lint常见告警分析及解决措施告警号:708告警46PC-Lint常见告警分析及解决措施告警号:716

告警等级:2告警消息样例: XXX.cpp(201):error716:(Info--while(1)...)分析及解决措施:

while(1)的问题,请使用for(;;)替代PC-Lint常见告警分析及解决措施告警号:716告警47PC-Lint常见告警分析及解决措施告警号:717

告警等级:2告警消息样例: XXX.cpp(508):error717:(Info--do...while(0);)分析及解决措施:

使用-emacro进行屏蔽或者修改代码PC-Lint常见告警分析及解决措施告警号:717告警48PC-Lint常见告警分析及解决措施告警号:725

告警等级:2告警消息样例:XXX.cpp(311):error725:(Info--Expectedpositiveindentationfromline308)分析及解决措施:

有时候是因为Tab键或排版格式没有对齐造成PC-Lint常见告警分析及解决措施告警号:725告警等49PC-Lint常见告警分析及解决措施告警号:731

告警等级:2告警消息样例:XXX.cpp(331):error731:(Info--Booleanargumenttoequal/notequal)分析及解决措施:判断两个bool变量或表达式是否相等或不等时会出现此告警,如:if(monPer15!=m_bCollectOf15)当出现此告警时可以改为if((INT)monPer15!=(INT)m_bCollectOf15)可以消除此告警,如果象这样写也会出现此告警,如if(true==m_bFlag)只要改写为if(m_bFlag)就可以消除此告警了PC-Lint常见告警分析及解决措施告警号:731告警50PC-Lint常见告警分析及解决措施告警号:747

告警等级:2告警消息样例:XXX.cpp(1446):error747:(Info--Significantprototypecoercion(arg.no.2)inttobool)SetCrossTR(pSetting,period,false);//清除性能越限标记。分析及解决措施:类型转换问题,如SetThisCrossTR(pSetting,false);有此告警,改写成SetThisCrossTR(pSetting,(bool)false);则消除了这个告警,一般情况下尽量避免使用bool型变量PC-Lint常见告警分析及解决措施告警号:747告警等51PC-Lint常见告警分析及解决措施告警号:774告警等级:2告警消息样例:XXX.cpp(146):error774:(Info--Booleanwithin'if'alwaysevaluatestoTrue分析及解决措施:bool表达式总是真值或总是假值voidclaNameManager::ManagerDestroy(){ ASSERT(m_pNameTable!=NULL); m_pNameTable->HashDestroy(); if(m_pNameTable!=NULL) { deletem_pNameTable; m_pNameTable=NULL; }} 明显应该将HashDestroy放到if判断里面,并且要删除掉ASSERT那一行PC-Lint常见告警分析及解决措施告警号:774告警等52PC-Lint常见告警分析及解决措施告警号:785告警等级:2告警消息样例:XXX.cpp(639):error785:(Info--Toofewinitializersforaggregate)分析及解决措施:通常时给数组初始化赋值时没有给所有的赋值造成,可以将其他的也赋值完来消除这个问题。这个告警目前在平台中非常多,即使使用-e参数屏蔽也屏蔽不了,还是会出现,这就要求编码时养成良好的习惯。PC-Lint常见告警分析及解决措施告警号:785告警等53PC-Lint常见告警分析及解决措施告警号:786告警等级:2告警消息样例:XXX.cpp(2451):error786:(Info--Stringconcatenationwithininitializer)分析及解决措施:同一个字符串分成多行书写时,使用双引号进行连接出的告警,此告警主要是提示是否多个字符串在中间忘了用标点符号格开,有时候有些字符串很长,需要分成多行书写时也会使用多个双引号,这时可以使用//lint–save-786,//lint–restore来屏蔽PC-Lint常见告警分析及解决措施告警号:786告警等54PC-Lint常见告警分析及解决措施告警号:794告警等级:2告警消息样例:XXX.cpp(934):error794:(Info--Conceivableuseofnullpointer'p'inleftargumenttooperator'ptr-ptr'分析及解决措施:同告警613一样,指针未校验引起,如果校验是在函数外部保证的,可以使用ASSERT来避免此告警PC-Lint常见告警分析及解决措施告警号:794告警等55PC-Lint常见告警分析及解决措施告警号:796告警等级:2告警消息样例:XXX.cpp(396):error796:(Info--Conceivableaccessofout-of-boundspointer(1beyondendofdata)byoperator'unary*')分析及解决措施:指针有可能越界的问题,通常是由于没有校验分配空间长度引起PC-Lint常见告警分析及解决措施告警号:796告警等56PC-Lint常见告警分析及解决措施告警号:797告警等级:2告警消息样例:XXX.cpp(396):error797:(Info--Conceivablecreationofout-of-boundspointer(2beyondendofdata)byoperator'++'分析及解决措施:指针未做校验有可能引起越界,比如定义一个指针指向字符串,但是在使用p++操作时没有先判断指针是否会越界如可以判断*p!='\0'或校验指针和起点地址差是否超过预先分配的空间长度。PC-Lint常见告警分析及解决措施告警号:797告警57PC-Lint常见告警分析及解决措施告警号:801告警等级:3告警消息样例:XXX.cpp(340):error801:(Info--Useofgotoisdeprecated)分析及解决措施:使用了goto语句造成,有些人使用goto语句不规范,如果屏蔽会引发其他程序结构不合理的问题,所以在程序中还是不要使用goto语句。PC-Lint常见告警分析及解决措施告警号:801告警58PC-Lint常见告警分析及解决措施告警号:818告警等级:3告警消息样例:XXX.c(323):Info818:Pointerparameter'pGraph'(line206)couldbedeclaredaspointingtoconst分析及解决措施:这个问题产生主要是因为函数参数在函数中为只读的,可以申明为const类型,但是如果使用以下形式: typdefstructPOINT_t{ intx; inty;}POINT,*LPPOINT;intInsertPoint(LPPOINTpPoint);如果使用LPPOINT类型的指针类型来定义参数的话,即使改为constLPPOINTpPoint也仍然会有告警.必须改为constPOINT*pPoint才能消除此告警PC-Lint常见告警分析及解决措施告警号:818告警等59PC-Lint常见告警分析及解决措施告警号:825告警等级:3告警消息样例:XXX.cpp(2243):error825:(Info--controlflowsintocase/defaultwithout-fallthroughcomment)分析及解决措施:

使用//lint-fallthrough在代码里进行注释可以消除此告警PC-Lint常见告警分析及解决措施告警号:825告警60PC-Lint常见告警分析及解决措施告警号:826告警等级:3告警消息样例:XXX.cpp(290):error826:(Info--Suspiciouspointer-to-pointerconversion(areatoosmall))分析及解决措施:这个问题的产生通常是由于内存越界造成或将一个空间小的指针转换为一个空间大的指针造成,xxx.cpp中的代码为:pTailCheck=(DWORD*)((CHAR*)pBuf+pPtInfo->BufSize-VOS_PT_BUF_TAIL_LEN); 实际上是将CHAR*转换为DWORD*造成的。可以在本行前使用注释/*lint-save-e826*/屏蔽,在本行后再使用/*lint-restore*/恢复的办法PC-Lint常见告警分析及解决措施告警号:826告警61PC-Lint常见告警分析及解决措施告警号:834告警等级:3告警消息样例:intx=(rect.Width()-cxIcon+1)/2;XXX.cpp(178):Info834:Operator'-'followedbyoperator'+'isconfusing.Useparentheses.分析及解决措施:这个告警很简单,主要是需要使用括号将表达式按运算优先顺序括起来以方便阅读PC-Lint常见告警分析及解决措施告警号:834告警等62PC-Lint常见告警分析及解决措施告警号:1065告警等级:3告警消息样例:XXX.cpp(657):error1065:(Error--Symbol'VOS_TerminateHandle(void)'notdeclaredas"C"conflictswithline510)分析及解决措施:在头文件里被申明为extern"C",但在cpp文件里函数前没有加上extern"C"关键字造成PC-Lint常见告警分析及解决措施告警号:1065告警63PC-Lint常见告警分析及解决措施告警号:1540告警等级:3告警消息样例:XXX.cpp(495):error1540:(Warning--Pointermember'CXXXObject::m_pCrc4Fecses'(line76,XXXP.h,moduleYYY.cpp)neitherfreednorzero'edbydestructor)分析及解决措施:析构函数中没有对成员指针变量进行内存释放或清零操作,修改代码即可PC-Lint常见告警分析及解决措施告警号:1540告64PC-Lint常见告警分析及解决措施告警号:1732告警等级:3告警消息样例:XXX.cpp(48):error1732:(Info--newinconstructorforclass'FEC_CURRENT_DATA'whichhasnoassignmentoperator)分析及解决措施:在构造函数中调用new造成,所以在构造函数中尽量不要分配内存PC-Lint常见告警分析及解决措施告警号:1732告65PC-Lint常见告警分析及解决措施告警号:1733告警等级:3告警消息样例:XXX.cpp(11):error1733:(Info--newinconstructorforclass'ABXError'whichhasnocopyconstructor)分析及解决措施:在构造函数中使用了new函数,但没有拷贝构造函数有时会出现这个告警PC-Lint常见告警分析及解决措施告警号:173366PC-Lint常见告警分析及解决措施告警号:1735告警等级:3告警消息样例:Info1735:Virtualfunction'CXXXTest::Set(constchar*)'hasdefaultparameter分析及解决措施:这个问题产生主要是因为虚函数有缺省参数可以使用/*lint-save-e1735*/和/*lint-restore*/来屏蔽PC-Lint常见告警分析及解决措施告警号:1735告67PC-Lint常见告警分析及解决措施告警号:1740告警等级:3告警消息样例:XXX.cpp(101):error1740:(Info--pointermember'CXXXManager::m_pCpuChArr'(line184,fileYYY.h)notdirectlyfreedorzero'edbydestructor)分析及解决措施:调用了VOS_Free造成,可以使用/*lint-save-e1740*/和/*lint-restore*/来屏蔽,有时候定义了一个类的成员指针变量,析构函数没有释放或将指针赋空的话也会有此告警,只要在析构函数中将指针赋成0即可消除此告警。这个告警在平台中也是出现非常多的,即使使用-e1740也屏蔽不了。PC-Lint常见告警分析及解决措施告警号:1740告68PC-Lint常见告警分析及解决措施告警号:1762告警等级:3告警消息样例:XXX.cpp(265):error1762:(Info--MemberfunctionCXXXManager::GetXXXInfo(unsignedchar&,structXXX_INFO*&)'couldbemadeconst)分析及解决措施:函数可以申明为const类型,通常都是一些没有修改成员变量的函数会有这类告警PC-Lint常见告警分析及解决措施告警号:1762告69PC-Lint常见告警分析及解决措施告警号:1774告警等级:3告警消息样例:XXX.cpp(188):error1774:(Info--Couldusedynamic_casttodowncastpolymorphictype'IBase')分析及解决措施:在这里主要是LoadPlugin()函数本来返回值类型是IBase*,但把它转换成IPlugin*后是使用强制转换,没有使用dynamic_cast转换PC-Lint常见告警分析及解决措施告警号:177470PC-Lint常见告警分析及解决措施告警号:1776告警等级:3告警消息样例:XXX.cpp(198):error1776:(Info--Convertingastringliteraltosignedchar*isnotconstsafe(arg.no.4))#..._Malloc",(constchar*)__FILE__,__LINE__)分析及解决措施:主要是参数可以申明为const造成,象__FILE__前可以加(constchar*)进行转换,并且对应的VOS_Malloc()函数定义时需要将参数定义为constchar*类型PC-Lint常见告警分析及解决措施告警号:177671代码走查工具PCLint代码走查工具PCLint72目录PC-Lint简介PC-Lint基本使用方法PC-Lint常用选项PC-Lint在各种环境中的集成PC-Lint常见告警分析及解决措施目录PC-Lint简介73代码走查工具PCLint课件74代码走查工具PCLint课件75PC-Lint基本使用方法PC-Lint是一个命令行工具,因此使用方式是命令行带参数方式使用。一般的使用格式为: lint-nt.exe[Option]file1file2…如:lint-nt.exe-u-id:\lintstd.lntsample.c在这里-u表示只对本单元进行检查-id:\lint是表示会在d:\lint目录下搜索文件std.lnt是表示要使用的配置文件sample.c表示要检查的源文件PC-Lint基本使用方法PC-Lint是一个命令行工具,因76PC-Lint基本使用方法检查一个目录下的所有源文件可以使用以下方法:如:lint-nt.exe-u-id:\lintstd.lntd:\osp\vos\*.cpp跟前面不同的是这里将sample.c变成了d:\osp\vos\*.cpp,使用*.cpp的意思是它会检查d:\osp\vos目录下的所有.cpp文件,但是它不能检查子目录下的文件PC-Lint基本使用方法检查一个目录下的所有源文件可以使用77PC-Lint基本使用方法要检查所有包括子目录的文件可以使用以下方法: lint-nt-id:\lintstd.lntAllSource.lnt在AllSource.lnt文件中可以放置如下:Moudule1-Dir\*.cpp Moudule2-Dir\*.cpp Moudule3-Dir\*.cpp...当检查所有文件时不需要使用-u选项PC-Lint基本使用方法要检查所有包括子目录的文件可以使用78PC-Lint基本使用方法PC-Lint配置文件介绍PC-Lint使用那个配置文件是由命令行参数决定的,一般地都使用std.lnt文件,std.lnt文件中可以包含各种配置选项,还可以包含其他的配置文件,有点类似C的头文件,里面可以include许多其他头文件,不过PC-Lint配置文件包含其他配置文件不需要写include,直接写文件名就可以了。每个配置文件里都可以包含配置选项,这些配置选项也可以放在命令行中,一般为使用方便,命令行中不要放很多选项,尽量都将选项放到配置文件中PC-Lint基本使用方法PC-Lint配置文件介绍79PC-Lint基本使用方法以下是VC下的配置文件样例//Microtec32-bit,-si4-sp4,lib-w32.lnt//Standardlintoptionsco-msc60.lnt//PC-Lint提供的对VC6的告警屏蔽文件lib-w32.lnt//PC-Lint提供的对VC6库头文件的告警屏蔽文件options.lnt-si4-sp4//用户自定义的选项文件env-vc6.lnt//用户用来设置编辑环境的配置文件-id:\vc6\vc98\include//include目录-id:\vc6\vc98\mfc\include//include目录PC-Lint基本使用方法以下是VC下的配置文件样例80PC-Lint基本使用方法一般来说,PC-Lint经常会有一些误报,为了消除这些误报,不得不将程序风格改动来规避,但有时候怎么改写程序都有告警,比如说你定义了两个宏,前面那个宏里有一半大括号{,后面那个宏里有另一半大括号},这时候一定会有告警,你不得不使用一些PC-Lint选项来屏蔽这些告警。一般情况下,我们都将自己要写的选项放在Options.lnt文件中PC-Lint基本使用方法一般来说,PC-Lint经常会有一81PC-Lint基本使用方法另外还有关于编辑环境的问题,如果把PC-Lint集成到某个编辑环境中,那么他输入的格式必须和对应环境吻合才能保证在鼠标点击(或双击)错误消息条目时可以自动定位到对应源代码行,一般来说这类配置都放置在env-xxx.lnt文件中,如VC6的时env-vc6.lnt,SourceInsight的是env-si.lntPC-Lint本身提供了对各种编译器及对应库头文件的告警屏蔽文件,如co-msc60.lnt是对vc6的,lib-w32.lnt是对Win32库头文件告警的屏蔽配置文件PC-Lint基本使用方法另外还有关于编辑环境的问题,如果把82PC-Lint常用选项-i选项这个选项主要是用来设置include路径的如:-iD:\VC6\VC98\Include-e#选项这个选项主要是用来屏蔽告警号为#的告警如:-e818表示不显示告警号为818的告警-esym(#,符号名)选项这个选项主要是用来屏蔽告警号为#的某个符号的告警,如-esym(39,std)-emacro(#,宏名称)选项这个选项主要是用来屏蔽告警号为#的某个宏的告警PC-Lint常用选项-i选项83PC-Lint常用选项-dname[=value]这个选项主要是用来定义一个宏的如:-dWIN32,-dalpha=0-sp#表示指针的尺寸大小是#字节如:-sp4表示指针是4个字节大小-si#表示int的尺寸大小是字节如:-si4表示int型是4个字节大小-t#设置Tab键的大小为#个空格,缺省是8PC-Lint常用选项-dname[=value]84PC-Lint常用选项-sem选项这个选项主要是用来消除一些语义上的告警 比如说在一个函数A里面分配了内存,这时调用了另一个函数AddNode将分配的内存保存起来了,因此在函数A里面没有释放内存,如果使用PC-Lint检查会有内存泄漏方面的告警,因为PC-Lint不知道函数AddNode将分配的内存保存起来了,要消除这个告警就要用到-sem选项了。假设AddNode的第2个参数是用来保存分配内存,用法如下 -sem(AddNode,custodial(2)) 这里custodial关键字是表示保存的意思,2是表示第2个参数。 -sem选项还有些其他用法,大家可以看PC-Lint自带的pc-lint.pdf文件,里面有详细的解析PC-Lint常用选项-sem选项85PC-Lint常用选项-function(function0,function1,…)选项 这个选项一般情况下主要是用来表示function1及后面省略掉的函数和function0有类似的行为。 如:-function(malloc,mymalloc1,mymalloc2)表示mymalloc1,mymalloc2和malloc有类似的行为,因为malloc是用来分配内存的,所以pc-lint在检查mymalloc1和mymalloc2时也会想检查malloc一样看是否有释放掉 象上一页里已经定义了AddNode为保存内存的函数,如果碰到还有一个函数AddEvent也是有保存内存的功能,我们除了可以使用-sem(AddEvent,custodial(2))外,也可以使用-function(AddNode,AddEvent),效果是一样的。不过要注意的是AddEvent保存内存的参数也要和AddNode一样是第2个。PC-Lint常用选项-function(function086PC-Lint常用选项-format选项 这个选项主要是用来设置输出告警消息格式的,以便于可以和编辑环境格式一样,便于自动定位到告警对应的源代码 如对SourceInsight,-format选项的使用如下:-"format=%f%l%t%n:%m“这里%f表示文件名%l表示代码行号%t表示告警类型,如warning,error等%n表示PC-Lint的告警号%m表示PC-Lint输出的告警文本信息PC-Lint常用选项-format选项87PC-Lint常用选项-fallthrough 这个选项主要是用在switchcase中没有使用break的情况 可以在代码中使用//lint–fallthrough来消除没有使用break的告警-save 保存错误抑制状态 如:在代码中使用//lint–save–e429则表示从这行开始之后的代码抑制429告警的出现,直到使用//lint–restore来进行恢复后才会重新出现429告警-restore 重新设置错误抑制状态,使用-save选项抑制的告警将重新恢复,在使用了-save选项后一定要记住使用-restore进行恢复,否则可能有许多告警就被屏蔽调不出现了。PC-Lint常用选项-fallthrough88PC-Lint常用选项其他一些常用选项还有-elib抑制库头文件的告警-elibsym抑制库头文件中某个符号的告警-wlevel设置告警级别-efile用来抑制一个或多个文件里的告警-efunc用来抑制一个或多个函数里的告警+rw设置保留关键字等等。象-efile,-wlevel这些告警不要轻易使用这些选项的具体用法请看pc-lint.pdf文件PC-Lint常用选项其他一些常用选项还有89PC-Lint在各种环境中的集成PC-Lint在各种环境中的集成方法原理都是一样的,只要掌握前面讲的基本用法,知道如何用命令行来检测单个文件,一个目录下的所有文件,许多目录下的所有文件等,然后再结合各种环境的具体设置,就可以很方便地将PC-Lint集成到各种应用环境中了。下面将以VC6,SourceInsight,UltraEdit,Tornado四种环境为例讲述如何集成PC-LintPC-Lint在各种环境中的集成PC-Lint在各种环境中的90PC-Lint在各种环境中的集成在vc环境中集成在VC的Tools菜单中,按Customize…会出现下一页出现的对话框先在上面的列表框里增加一个条目,里面填上PC-Lint80,文本内容可以是其他的,由你自己决定。然后在Command:这一栏中输入PC-Lint的执行文件名,要带上目录再在Arguments:一栏里填上 -u-iC:\Lintstd.lnt$(FileName) 这里$(FileName)表示VC窗口里当前打开的文件名 你也可以将它改成$(FileDir)\*.cpp表示检查当前打开文件同一目录下的所有.cpp文件,通常用于检查一个模块 还可以改成AllSource.lnt,象前面讲过的一样,AllSource.lnt是一个放置有所有文件的配置文件,这时要将-u去掉。PC-Lint在各种环境中的集成在vc环境中集成91PC-Lint在各种环境中的集成PC-Lint在各种环境中的集成92PC-Lint在各种环境中的集成再在InitialDirectory一栏里填上$(FileDir) 最后再将useoutputwindow打上勾就完成了将PC-Lint集成到VC环境中PC-Lint在各种环境中的集成再在InitialDire93PC-Lint在各种环境中的集成在SourceInsight3.1中的集成在SourceInsight3.1中集成PC-Lint过程如下: 1)从Options菜单中选择“CustomCommands”命令项。 2)点Add键会出现下面的AddNewCustomCommand对话框在Newcommandname:栏中输入“PC-lint80”,原则上这个名称可以随便起,只要你能搞清楚它的含义就可以了,然后按OK按钮。

PC-Lint在各种环境中的集成在SourceInsight94PC-Lint在各种环境中的集成 3)在Run栏中输入“d:\lint\lint-nt-u-ic:\lintstd.lntenv-si%f”其中d:\lint是你PC-LINT的安装目录,%f是表示当前打开的文件。如果要Lint多个文件则需要使用配置文件,在配置文件里包含多个文件,将%f改成你自己的配置文件即可。 4)在Output栏中选择“IconicWindow”、“CaptureOutput”。 5)在Control栏中选择“SaveFilesFirst”、将缺省打了勾选上的“PauseWhenDone”改成不选择。 6)在SourceLinksinOutput栏中选择“ParseLinksinOutput”、“File,thenLine”。 7)在Pattern栏中将缺省设置改成^\([^]*\)\([0-9]+\)就大功告成了。 8)如果需要Lint当前打开文件的同一目录下所有文件,可以将%f改成%d\*.cpp 如下图:PC-Lint在各种环境中的集成 3)在Run栏中输入“d:95PC-Lint在各种环境中的集成PC-Lint在各种环境中的集成96PC-Lint在各种环境中的集成在Tornado2.0环境中集成在Tornado2.0的Tools菜单中点Customize…后会出现如下一页的对话框。先在对话框中按Add…按钮在MenuText一栏中输入PC-Lint80在ToolCommand:一栏中输入D:\LINT\lint-nt.exe-iD:\Lintstd.lnt$filename你也可以象前面讲过VC中集成一样,将$filename改成$filedir\*.cpp或AllSource.lnt在Working一栏中输入$filedir再将RedirecttoChildWind选上,按OK就可以了PC-Lint在各种环境中的集成在Tornado2.0环境中97PC-Lint在各种环境中的集成PC-Lint在各种环境中的集成98PC-Lint在各种环境中的集成在UltraEdit环境中集成在Advanced菜单中选ToolConfiguration...,显示图如下一页所示在commandline:中填写: d:\lint\lint-nt–iD:\Lintstd.lnt%F在MenuItem中填写:PC-Lint80在CommandOutput中选择:(x)OutputtoListBox和(x)CaptureOutput5)按Insert按钮再按OK按钮就可以了PC-Lint在各种环境中的集成在UltraEdit环境中集99PC-Lint在各种环境中的集成PC-Lint在各种环境中的集成100PC-Lint常见告警分析及解决措施PC-Lint的告警级别定义如下:PC-Lint常见告警分析及解决措施PC-Lint的告警级别101PC-Lint常见告警分析及解决措施PC-Lint告警分为0~4级,其中0级是内部错误或致命错误,1级告警是句法错误,2级告警是警告,3级是信息,4级是可选的,4级缺省是不打开的。0级告警是不允许出现的,1级告警一般也是不允许出现的,如果出现,说明可能PC-Lint配置上可能有问题,或者程序根本编译不过,2级告警一般也是不能屏蔽的,2级告警很多是内存资源没有释放,指针越界一类的警告,会产生严重问题,3级告警有些告警也是非常重要的,会引起严重问题,有些告警属于提示信息,问题不是很大,所以3级告警里要分情况对待。0~2级告警都不能使用-e选项进行屏蔽,只能使用-esym,-emacro,-sem之类的选项进行屏蔽;3级告警要根据具体情况,有些可以使用-e选项进行屏蔽,有些不可以。下面就对经常遇到的一些告警进行详细的分析及讨论解决措施。PC-Lint常见告警分析及解决措施PC-Lint告警分为0102PC-Lint常见告警分析及解决措施告警号:39

告警等级:1告警消息样例: stl_type_traits.h(279):error39:(Error--Redefinitionofsymbol'__type_traits<constsignedchar*>'conflictswithline271)分析及解决措施:

可以使用-esym(39,符号名)来消除此告警,在这里可以使用

-esym(39,__type_traits<constsignedchar*>PC-Lint常见告警分析及解决措施告警号:39告警等103PC-Lint常见告警分析及解决措施告警号:402

告警等级:2告警消息样例: XXX.cpp(77):error402:(Warning--staticfunction'VOS_GetFixedStackDepth(void)'(line77)分析及解决措施:

主要是函数原型申明为静态的,但函数实体确漏写了static造成PC-Lint常见告警分析及解决措施告警号:402告警104PC-Lint常见告警分析及解决措施告警号:413

告警等级:2告警消息样例: xxx.cpp(1118):error413:(Warning--Likelyuseofnullpointerunknown-name'inargumenttooperatorunary*分析及解决措施:

指针未校验引起,如果确认指针可以由外部保证则可以使用ASSERT来消除此告警PC-Lint常见告警分析及解决措施告警号:413告警105PC-Lint常见告警分析及解决措施告警号:429

告警等级:2告警消息样例: XXX.cpp(2474):error429:(Warning--Custodialpointer'pEvent'(line2459)hasnotbeenfreedorreturned)分析及解决措施: AddEvent将指针pEvent保存起来,解决办法是使用 -sem(ISystem::AddEvent,1p,custodial(1))来屏蔽此告警,这里1p是表示第1个参数,custodial(1)是表示第1个参数被保留起来了。 另外还有函数递归调用时,如果递归调用时使用的参数和函数参数同名也会出现此告警,递归调用时必须将参数改名。还有一种情况是在父函数里分配了内存,传递到子函数后,由于子函数里有return语句有时也会产生429告警,这种行为非常奇怪,目前没有找到好的消除办法,尽量将程序结构改成把return语句去掉就没有这个告警了。PC-Lint常见告警分析及解决措施告警号:429告警106PC-Lint常见告警分析及解决措施告警号:522

告警等级:2告警消息样例: error522:(Warnin

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论