PC-lint 的代码实例

下面这些例子说明FlexeLint/PC-lint的一些功能。通过修改这些代码样本,可以分析它们的原因和处理结果。

“Off-By-One”错误实例(C源码)

下面的例子说明了FlexeLint/PC-lint为什么会出现“Off-By-One”错误。

/* Off-By-One Example */
#include 
int main()
{ 
int i; 
int a[] = {1,2,3}; 
int n = sizeof(a)/sizeof(int);
for(i=0;i<=n;i++)
printf("a[%d]=%d\n",i,a[i]); 
return 0;
}

“Multi-pass”实例(C源码)

这个实例说明了FlexeLint/PC-lint's分析后的伪执行能力。注意使用嵌入的lint选项。

//lint -passes(4)

int f( int n )
{
return 10/n;
}

int g( int n )
{
if( n == -1 ) return 0;
return f(n) + g( n - 1 );
}

int main()
{
return g( 3 );
}

基于规则的语法(C源码)

这个例子说明了FlexeLint/PC-lint是怎样进行语法检查的。

下面的例子演示了如何使用语义选项。

  • lint -sem( fill, 1p >= N ) :“fill” 的含义是指向一个长度至少为N的区域。

  • lint -sem( copy, @p == 1p ): “copy”的返回值指向一个大小(“copy“的第一个参数值)等于该区域的区域

注释:

  • "1p" 是一个区域的长度,由给定函数的第一个参数指定。

  • "@p" 是一个区域的长度,由给定函数的返回值指定。

#include 
#include 
void fill( char * );
char *copy( char * ); 

#define N 100

基于规则的语法(C++源码)

这个例子说明了一个简单的C++程序是如何出现错误的。

#include 

class X
{
int *p;
public:
X()
{ p = new int[20]; }
void init()
{ memset( p, 20, 'a' ); }
~X()
{ delete p; }
};

Strong typedef检查实例(C++源码)

这个例子说明了FlexeLint/PC-lint是怎样检查Strong typedef用法的。

Strong typedef,可以使FlexeLint可以在不匹配的情况下给报告分配标称。下面是函数combine()中的错误报告。之后的选项将赋予它们三个强大的stypedef名(之后会定义它们) ,并具有AcJcX的特性。它们的含义是报告分别在分配冲突给typedef时 (但不包括c-onstants),加入typedef时 (但不包括constants) 和从typedef中提取。

lint -strong( AcJcX, Length, H_Position, V_Position ) 

#define Max(x,y) ((x) >= (y) ? (x) : (y))
#define Min(x,y) ((x) >= (y) ? (y) : (x))

以下三种typedef


// types
typedef int Length;
typedef Length H_Position;
typedef Length V_Position; struct Point
{
H_Position x; // horizontal position
V_Position y; // vertical position
};

struct Rectangle
{
Point ul; // upper left boundary
Point lr; // lower right boundary
};

下面的函数计算没有complaint。长度使用H_Position和V_Position的通用形式定义。

Length perimeter( const Rectangle &r )
{
Length len = 0;
len += 2 * (r.ul.y - r.lr.y); // combining V_Position with Length
len += 2 * (r.lr.x - r.ul.x); // combining H_Position with Length
return len;
}

下面的函数绘制了一些合理的complaints。在这个函数中,需要H_Position和V_Position两种类型。它们被视为不能合并的,单独不同的类型。当这种情况出现的时候,就会发出警告。
combine(r1,r2) :形成一个刚好覆盖r1和r2的大矩阵。

Rectangle combine( const Rectangle &r1, const Rectangle &r2 )
{
Rectangle r;

r.ul.x = Min( r1.ul.x, r2.ul.x ); // OK
r.ul.y = Max( r1.ul.y, r2.ul.y ); // OK
r.lr.x = Max( r1.lr.y, r2.lr.x ); // Complain
r.lr.y = Min( r1.lr.x, r2.lr.x ); // Complain
return r;
}

引入多个模块

这个例子介绍了FlexeLint/PC-lint如何跨模块分析 。

当多个模块(即单独的编译单元)呈递给FlexeLint时,将被当做同一应用的部分来处理。FlexeLint的跨模块功能使它拥有编译人员不具备的透视功能。 然而,早期的版本中限制使用者只能同时编辑和提交一个文本。所以那时,编程人员没有办法在线测试多个模块。这就导致了很多人没有办法在多模块中写出有意义的报告。

一个.mm文件应该包含如下形式:
第一行评论
第二行评论
……
第N行评论
第一个模块名
……
最后一个模块名
第一个标题名
……
最后一个标题名

所有的'@'指令必须从第1列开始。注释行是可选的。 实际的C或C ++源代码可选择定义。没有必要把标题放在每个模块的后面。它们可以自由穿插。此外,空白行可以在整个文中中穿插。 模块可以有 .c 或 .cpp扩展或两者的混合。

如下例:

@module c1.cpp
#include "c.h"
int f()
{
return g(0) + 2;
}

@module c2.cpp
#include "c.h"
int g( int *p )
{
return ++*p;
}

@header c.h
int g( int * );

多模块的初始化和冗余

这个例子说明FlexeLint/PC-lint如何进行跨模块初始化顺序问题的检测。

本实例说明初始化中a.cpp的a变量和b.cpp的b变量的检测。还说明了对ab.h中未使用元素的检测。 随着时间的推移可以聚集不再使用的元素。注意区别对待stdio.h和 ab.h。 stdio.h在应用中有许多没有使用的声明,但这些没有被说明。ab.h中未被使用的声明会报告出来。

@module a.cpp
#include 
#include "ab.h"

int a = f();
int main()
{
printf( "b is %d\n", b );
return 0;
}

@module b.cpp

#include "ab.h"

int b = a;
int f()
{
return 3;
}

@header ab.h

extern int f(void);
extern int a;
extern int b;
typedef int INT32;
#define ReturnValue 3
struct A { int a, b; };

FlexeLint/PC-lint最新下载地址

你可能感兴趣的:(PC-lint 的代码实例)