当前位置

网站首页> 程序设计 > 开源项目 > 程序开发 > 浏览文章

PC-lint 的代码实例

作者:小梦 来源: 网络 时间: 2024-08-29 阅读:

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

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

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

/* Off-By-One Example */#include <stdio.h>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 <stdlib.h>#include <string.h>void fill( char * );char *copy( char * ); #define N 100

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

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

#include <string.h>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

// typestypedef int Length;typedef Length H_Position;typedef Length V_Position; struct Point{H_Position x; // horizontal positionV_Position y; // vertical position};struct Rectangle{Point ul; // upper left boundaryPoint 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 Lengthlen += 2 * (r.lr.x - r.ul.x); // combining H_Position with Lengthreturn 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 ); // OKr.ul.y = Max( r1.ul.y, r2.ul.y ); // OKr.lr.x = Max( r1.lr.y, r2.lr.x ); // Complainr.lr.y = Min( r1.lr.x, r2.lr.x ); // Complainreturn 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.hint 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 <stdio.h>#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.hextern int f(void);extern int a;extern int b;typedef int INT32;#define ReturnValue 3struct A { int a, b; };

FlexeLint/PC-lint最新下载地址

热点阅读

网友最爱