代码静态检查工具 PC-Lint

xujunlucky 贡献于2014-08-30

作者 微软用户  创建于2014-03-02 02:44:00   修改者徐军  修改于2014-07-07 09:46:00字数9188

文档摘要: PC-Lint工具当前最新版本为PC-LintV9.0,由GimpelSoftware公司发布()。PC-Lint在全球拥有广泛的客户群,许多大型的软件研发组织都把PC-Lint检查作为代码走查的第一道工序。PC-Lint不但能够对程式进行全局分析,识别没有被适当检验的数组下标,报告未被初始化的变量,警告使用空指针连同冗余的代码等,还能够有效地提出许多程序在空间利用、运行效率上的改进点。
关键词:

代码静态检查工具PC-Lint 1 PC-Lint工具 1.1 简介 PC-Lint工具当前最新版本为PC-Lint V9.0,由Gimpel Software 公司发布(http://www.gimpel.com/html/lint90.htm)。PC- Lint在全球拥有广泛的客户群,许多大型的软件研发组织都把PC-Lint 检查作为代码走查的第一道工序。PC-Lint 不但能够对程式进行全局分析,识别没有被适当检验的数组下标,报告未被初始化的变量,警告使用空指针连同冗余的代码等,还能够有效地提出许多程序在空间利用、运行效率上的改进点。 在很多专业级的软件公司,比如Microsoft、华为、中兴,PC-Lint检查无错误无警告是代码首先要过的第一关。 1.2 特点 1、PC-Lint是一种静态代码检测工具,可以说,PC- Lint是一种更加严格的编译器,不仅可以象普通编译器那样检查出一般的语法错误,还可以检查出那些虽然完全合乎语法要求,但很可能是潜在的、不易发现的逻辑错误。 2、PC- Lint不但可以检测单个文件,也可以从整个项目的角度来检测问题,因为C语言编译器固有的单个编译,这些问题在编译器环境下很难被检测,而PC-Lint在检查当前文件的同时还会检查所有与之相关的文件,可想而知,它会对我们有很大的帮助。 3、 PC- Lint支持几乎所有流行的编辑环境和编译器,比如Borland C++从1.x到5.x各个版本、Borland C++ Build、GCC、VC、VS、watcomC/C++、Source insight、Tornado 2.0、intel C/C++等等,也支持16/32/64的平台环境。 4、支持Scott Meyes的名著(Effective C++/More Effective C++)中说描述的各种提高效率和防止错误的方法。 5、PC-Lint查找代码的缺陷和错误,分析代码存在的潜在问题,比编译器更加严格。 1.3 应用设想 1、 将PC-Lint工具与软件开发IDE集成,如vs2010、SourceInsight,Tornado或者独立的命令行执行。编码人员在开发过程中,可以随时的运行PC- Lint对自己的编码进行检查,消除告警。 2、 各个软件的代码在入CC库前进行集中的PC- Lint,在消除告警后才能入CC库。 3、 将PC- Lint集成到基于ClearCase的持续集成环境中,在每一次构建过程中运行PC-lint对项目中的所有代码进行检查,并提交检查结果报告,让对应软件编码人员消除告警。 软件开发人员在软件开发活动中,不仅要重视软件的设计,也要重视编码的质量。目前,对软件编码质量的检查主要集中在单元测试阶段,而应用PC-Lint工具可以将这一过程前移到编码阶段,好处有两个:一、编码人员对代码最熟悉,而且编码过程中去修正告警,效率最高,同时保证了时效性;二、减少单元测试人员的一部分工作量,注意力可以主要的集中在测试用例与执行上面。 1.4 应用不可控因素 1、 期望工具完全符合公司的规范要求,需要对工具进行一定的配置。 2、 工具的可推广性,各个软件编码人员是否愿意接受,并落实使用,目前不好预测。 3、 需评估与现有TestBed的完全兼容性,对于检查结果,质量流程采信于哪个工具,目前未知。 4、 售后支持不足,网上搜索未发现明显国内代理。 1.5 报价 New Product Pricing - Version 9.00 US $ PC-lint for C/C++ Version 9.0     PC-lint - One Workstation License (non-floating) 389.00   PC-lint - 10 User ONE-location LAN License 3500.00        PC-lint - Additional Users beyond 10 @ $300 each 2 应用实例 2.1 Example(1) 1 /* Off-By-One Example */ 2 #include 3 int main() 4 { 5 int i; 6 int a[] = {1,2,3}; 7 int n = sizeof(a)/sizeof(int); 8 for(i=0;i<=n;i++) 9 printf("a[%d]=%d\n",i,a[i]); offbyone.c 9 Warning 661: Possible access of out-of-bounds pointer (1 beyond end of data) by operator '[' [Reference: file offbyone.c: lines 7, 8, 9] 10 _ 11 if(i=10) offbyone.c 11 Info 720: Boolean test of assignment offbyone.c 11 Warning 506: Constant value Boolean offbyone.c 11 Info 774: Boolean within 'if' always evaluates to True [Reference: file offbyone.c: line 11] 12 { 13 i++; 14 } _ 15 return 0; offbyone.c 15 Warning 438: Last value assigned to variable 'i' (defined at line 5) not used 16 } 2.2 Example(2)      1  /* Off-By-One Example */      2  #include       3  int main()      4  {       5    int i;       6    int a[] = {1,2,3};       7    int n = sizeof(a)/sizeof(int);      8    for(i=0;i<=n;i++)                                        _      9      printf("a[%d]=%d\n",i,a[i]);  offbyone.c  9  Warning 661:  Possible access of out-of-bounds pointer (1 beyond end of data) by operator '[' [Reference: file offbyone.c: lines 7, 8, 9]     10    return 0;     11  }     12   2.3 Example(3) 1 //lint -passes(4) 2 3 int f( int n ) 4 { 5 return 10/n; During Specific Walk: multipass.c 16 g(3) #2 multipass.c 11 g(2) #3 multipass.c 11 g(1) #4 multipass.c 11 g(0) #5 multipass.c 11 f(0) #5 multipass.c 5 Warning 414: Possible division by 0 [Reference: file multipass.c: lines 11, 16] 6 } 7 8 int g( int n ) 9 { 10 if( n == -1 ) return 0; 11 return f(n) + g( n - 1 ); 12 } 13 14 int main() 15 { 16 return g( 3 ); 17 } 18 19 2.4 Example(4) #include 16 #include 17 void fill( char * ); 18 char *copy( char * ); 19 20 #define N 100 21 22 void f() 23 { 24 char buffer[N]; 25 char *p; 26 char *q; 27 28 p = (char *) malloc( N ); _ 29 p++; semantics.c 29 Warning 613: Possible use of null pointer 'p' in argument to operator '++' [Reference: file semantics.c: line 28] semantics.c 29 Info 810: Arithmetic modification of custodial pointer 'p' 30 fill( buffer ); _ 31 fill( p ); semantics.c 31 Warning 426: Call to function 'fill(char *)' violates semantic '(1p>=N)' 32 q = copy( p ); 33 strcpy( q, buffer ); _ 34 free( buffer ); semantics.c 34 Warning 424: Inappropriate deallocation (free) for 'auto' data _ 35 free( p ); semantics.c 35 Warning 424: Inappropriate deallocation (free) for 'modified' data 36 } 37 38 --- Global Wrap-up Info 714: Symbol 'f(void)' (line 22, file semantics.c) not referenced Warning 526: Symbol 'fill(char *)' (line 17, file semantics.c) not defined Warning 526: Symbol 'copy(char *)' (line 18, file semantics.c) not defined 2.5 Example(5) 1 #include 2 3 class X 4 { 5 int *p; 6 public: 7 X() 8 { p = new int[20]; } 9 void init() 10 { memset( p, 20, 'a' ); } 11 ~X() 12 { delete p; } _ 8 { p = new int[20]; } simple.cpp 8 Info 1732: new in constructor for class 'X' which has no assignment operator simple.cpp 8 Info 1733: new in constructor for class 'X' which has no copy constructor _ 10 { memset( p, 20, 'a' ); } simple.cpp 10 Warning 669: Possible data overrun for function 'memset(void *, int, unsigned int)', argument 3 (size=97) exceeds argument 1 (size=80) [Reference: file simple.cpp: lines 8, 10] _ 12 { delete p; } simple.cpp 12 Warning 424: Inappropriate deallocation (delete) for 'new[]' data 13 }; 14 --- Wrap-up for Module: simple.cpp Info 753: local class 'X' (line 3, file simple.cpp) not referenced --- Global Wrap-up Info 1714: Member function 'X::init(void)' (line 9, file simple.cpp) not referenced 2.6 Example(6) 1 /* General Test Example */ 2 3 #include 4 #include 5 #include 6 _ 7 #define Extract(ch) (ch) & 0xFf generaltest.cpp 7 Info 773: Expression-like macro 'Extract' not parenthesized 8 #define Value(ch) ((ch) > '0' && \ 9 (ch) <= '9' ? (ch) - '0' : 0) 10 #define Abs(x) ( (x) < 0 ? -x : (x) ) 11 12 void readline( char *fn ) 13 { 14 FILE *f; 15 char buf[100]; 16 17 if( !fn ) printf( "bad file\n" ); _ 18 f = fopen( fn, "r" ); generaltest.cpp 18 Warning 668: Possibly passing a null pointer to function 'fopen(const char *, const char *)', arg. no. 1 [Reference: file generaltest.cpp: line 17] _ 19 (void) fgets( buf, 101, f ); generaltest.cpp 19 Warning 668: Possibly passing a null pointer to function 'fgets(char *, int, struct _IO_FILE *)', arg. no. 3 [Reference: file generaltest.cpp: line 18] generaltest.cpp 19 Warning 419: Apparent data overrun for function 'fgets(char *, int, struct _IO_FILE *)', argument 2 (size=101) exceeds argument 1 (size=100) [Reference: file generaltest.cpp: line 19] 20 fclose( f ); _ 21 } generaltest.cpp 21 Info 818: Pointer parameter 'fn' (line 12) could be declared as pointing to const 22 23 int compute( char *s ) 24 { 25 int sum = 0; 26 while( *s ) _ 27 sum = sum + Value(Extract(*s++)); generaltest.cpp 27 Warning 666: Expression with side effects passed to repeated parameter 1 in macro 'Value' _ 28 return Abs( sum - 100 ); generaltest.cpp 28 Warning 665: Unparenthesized parameter 1 in macro 'Abs' is passed an expression _ 29 } generaltest.cpp 29 Info 818: Pointer parameter 's' (line 23) could be declared as pointing to const 30 31 class String 32 { 33 private: 34 char *a; 35 unsigned len; 36 public: 37 String( char *s = 0 ) 38 { 39 if( s ) 40 { 41 len = strlen(s); 42 a = new char[len]; 43 strcpy( a, s ); 44 } 45 } 46 ~String() { len = 0; } 47 String( const String & ); 48 String & operator=( const String &s ) 49 { 50 len = s.len; 51 a = new char[len]; 52 memcpy( a, s.a, len ); 53 return s; 54 } _ 45 } generaltest.cpp 45 Info 818: Pointer parameter 's' (line 37) could be declared as pointing to const generaltest.cpp 45 Warning 1541: Member 'String::a' (line 34) possibly not initialized by constructor generaltest.cpp 45 Warning 1541: Member 'String::len' (line 35) possibly not initialized by constructor _ 46 ~String() { len = 0; } generaltest.cpp 46 Warning 1540: Pointer member 'String::a' (line 34) neither freed nor zeroed by destructor _ 51 a = new char[len]; generaltest.cpp 51 Warning 423: Creation of memory leak in assignment to 'String::a' _ 53 return s; generaltest.cpp 53 Info 1772: Assignment operator 'String::operator=(const String &)' is not returning *this generaltest.cpp 53 Error 1058: Initializing a non-const reference 'String &' with a value of type 'const String' generaltest.cpp 53 Warning 1413: function 'String::operator=(const String &)' is returning a temporary via a reference generaltest.cpp 53 Warning 1561: Reference initialization causes loss of const/volatile integrity (return) _ 54 } generaltest.cpp 54 Warning 1529: Symbol 'String::operator=(const String &)' not first checking for assignment to this 55 }; 56 57 --- Wrap-up for Module: generaltest.cpp Info 753: local class 'String' (line 31, file generaltest.cpp) not referenced Info 754: local structure member 'String::String(const String &)' (line 47, file generaltest.cpp) not referenced Info 766: Header file 'stdlib.h' not used in module 'generaltest.cpp' --- Global Wrap-up Info 714: Symbol 'readline(char *)' (line 12, file generaltest.cpp) not referenced Info 714: Symbol 'compute(char *)' (line 23, file generaltest.cpp) not referenced Info 1714: Member function 'String::String(const String &)' (line 47, file generaltest.cpp) not referenced Warning 1526: Member function 'String::String(const String &)' (line 47, file generaltest.cpp) not defined Info 1714: Member function 'String::operator=(const String &)' (line 48, file generaltest.cpp) not referenced 2.7 Example(6) 1 #include 2 3 class X 4 { 5 int *p; 6 public: 7 X() 8 { p = new int[20]; } 9 void init() 10 { memset( p, 20, 'a' ); } 11 ~X() 12 { delete p; } _ 8 { p = new int[20]; } simple.cpp 8 Info 1732: new in constructor for class 'X' which has no assignment operator simple.cpp 8 Info 1733: new in constructor for class 'X' which has no copy constructor _ 10 { memset( p, 20, 'a' ); } simple.cpp 10 Warning 669: Possible data overrun for function 'memset(void *, int, unsigned int)', argument 3 (size=97) exceeds argument 1 (size=80) [Reference: file simple.cpp: lines 8, 10] _ 12 { delete p; } simple.cpp 12 Warning 424: Inappropriate deallocation (delete) for 'new[]' data 13 }; 14 15 test() _ 16 { simple.cpp 16 Info 745: function 'test(void)' has no explicit type or class, int assumed 17 int *p=new int[100]; 18 int j; 19 for(j=0;j<101;j++) _ 20 p[j]=j; simple.cpp 20 Info 725: Expected positive indentation from line 19 simple.cpp 20 Warning 661: Possible access of out-of-bounds pointer (1 beyond end of data) by operator '[' [Reference: file simple.cpp: lines 17, 19, 20] 21 _ 22 delete[] j; simple.cpp 22 Error 1043: Attempting to 'delete' a non-pointer simple.cpp 22 Warning 522: Highest operation, symbol reference 'j', lacks side-effects 23 24 _ 25 } simple.cpp 25 Info 783: Line does not end with new-line simple.cpp 25 Warning 533: function 'test(void)' should return a value (see line 15) simple.cpp 25 Warning 429: Custodial pointer 'p' (line 17) has not been freed or returned --- Wrap-up for Module: simple.cpp Info 753: local class 'X' (line 3, file simple.cpp) not referenced --- Global Wrap-up Info 714: Symbol 'test(void)' (line 15, file simple.cpp) not referenced Info 1714: Member function 'X::init(void)' (line 9, file simple.cpp) not referenced

下载文档到电脑,查找使用更方便

文档的实际排版效果,会与网站的显示效果略有不同!!

需要 5 金币 [ 分享文档获得金币 ] 0 人已下载

下载文档