PC-Lint 是 C/C++ 软件代码静态分析工具,你可以把它看作是一种更加严格的编译器。它不仅可以检查出一般的语法错误,还可以检查出那些虽然符合语法要求但不易发现的潜在错误。
C 语言的灵活性带来了代码效率的提升,但相应带来了代码编写的随意性,另外 C 编译器不进行强制类型检查,也带来了代码编写的隐患。 PCLint 识别并报告 C 语言中的编程陷阱和格式缺陷的发生。它进行程序的全局分析,能识别没有被适当检验的数组下标,报告未被初始化的变量,警告使用空指针,冗余的代码,等等。软件除错是软件项目开发成本和延误的主要因素。 PClint 能够帮你在程序动态测试之前发现编码错误。这样消除错误的成本更低。
使用 PC-Lint 在代码走读和单元测试之前进行检查,可以提前发现程序隐藏错误,提高代码质量,节省测试时间。并提供编码规则检查,规范软件人员的编码行为。
由于 PC-LINT 对于一般程序员来说可能比较陌生,有好多人安装了也不知道怎样配置和使用。
下面我就根据自己的安装和配置心得对 PC-Lint 的安装、配置及使用进行下详细说明 . 本人主要介绍了将 PC-Lint 集成到 VC++6.0 和 SourceInsight 的方法和步骤。
( 一 )Windows 下 C/C++ 开发工具中, VC6 使用较为普遍,因此这里先讲下 VC6.0 环境中集成 pclint 的步骤 .
首先 , 当然要下载软件,正版软件要 200 多 $ 呢,买不起!所以只好网上找免费的拉。从 http://www.61ic.com/down/othe/pclint.rar 处可以下载到一个 8.0 版本的 pclint.
1. 将 pclint.rar 解压至 c:/, 这样 lint 文件就位与 c:/pclint( 安装目录 ) 下了。
2. 将 c:/pclint/lnt 下的 3 个文件 lib-w32.lnt , env-vc6.lnt , co-msc60.lnt 拷贝至 c:/pclint 下, 再在安装目录下创建 std.lnt 和 options.lnt 两个文件,其中 std.lnt 的内容如下
// contents of std.lnt
c:/pclint/co-msc60.lnt
c:/pclint/lib-w32.lnt
c:/pclint/options.lnt -si4 -sp4
-i"D:/Program Files;D:/Program Files/Microsoft Visual Studio/VC98/Include"
//end
其中 -i 后面的路径名为 VC 的安装路径和 VC Include 文件路径,根据自己的修改便可。
options.lnt 内容可为空,为定制内容 , 以后需要时再添加。
准备工作做完了,下一步就是要将 pclint 集成到 VC6 中去,先配置 lint 使之能对单个 C 或 C++ 文件进行检查。
1. 打开 VC6 , tools--->customize-->tools 新建一个名为 PC-Lint 的项,在下面填入
command: C:/pclint/lint-nt.exe
arguments: -u c:/pclint/std.lnt c:/pclint/env-vc6.lnt "$(FilePath)"
Use Output Window 打上勾
close 完成。 这个在你 VC 窗口 tools 菜单下应该多了一个 PC-Lint 选项,可以用它来运行 lint 程序,对你的 c/c++ 代码进行静态检查了。
( 自己注 1 :将 pclint 放在任何目录都是可以的,但是,如果是放在例如: Program Files 这样的目录中,由于该目录中间有空格,所以,解析时常常会出错,需要在绝对路径外面加上引号,例如: "H:/Program Files/pclint/lint-nt.exe"
自己注 2 :其实,更简单的方法使 pc-lint 的安装路径设置到系统地 path 环境变量中,那么就完全可以使用相对路径了。
自己注 3 :运行时,会提示 PC-lint for C/C++ (NT) Ver. 8.00e, Copyright Gimpel Software 1985 -2001
c:/pclint/co-msc60.lnt(214) : Error 307: Can't open indirect file 'lib-ole.lnt'
Tool returned code: 2 这个错误,打开 co-msc60.lnt ,我们可以看到该文件最后一行对 'lib-ole.lnt' 的调用,简单的处理直接注释掉就行了,如需用到 OLE, 请设置 lib-ole.lnt 的绝对路径,并请参考下 pclint 的相关文档)
现在就可以用个小程序测试一下 pclint 了
//test1.cpp
#include <string.h>
class X
{
int *p;
public:
X()
{ p = new int[20]; }
void init()
{ memset( p, 20, 'a' ); }
~X()
{ delete p; }
};
编译这个文件,看下你的编译器给你多少警告,再运行下 lint , 可以自己对比一下。
我的机器上, VC 产生 0 errors 0 warnings, 而 lint 程序产生了如下 8 条警告信息 , 有些还是很有用处的提示,这里就不一一分析了 。
运行后出现的提示如下:
PC-lint for C/C++ (NT) Ver. 8.00e, Copyright Gimpel Software 1985-2001
--- Module: F:/C++ Test/lintRun.cpp
{ p = new int[20]; }
F:/C++ Test/lintRun.cpp(8): error 1732: (Info -- new in constructor for class 'X' which has no assignment operator)
F:/C++ Test/lintRun.cpp(8): error 1733: (Info -- new in constructor for class 'X' which has no copy constructor)
{ memset( p, 20, 'a' ); }
F:/C++ Test/lintRun.cpp(10): error 669: (Warning -- Possible data overrun for function 'memset(void *, int, unsigned int)', argument 3 (size=97) exceeds argument 1 (size=80) [Reference: file F:/C++ Test/lintRun.cpp: lines 8, 10])
F:/C++ Test/lintRun.cpp(8): error 831: (Info -- Reference cited in prior message)
F:/C++ Test/lintRun.cpp(10): error 831: (Info -- Reference cited in prior message)
{ delete p; }
F:/C++ Test/lintRun.cpp(12): error 424: (Warning -- Inappropriate deallocation (delete) for 'new[]' data)
--- Wrap-up for Module: F:/C++ Test/lintRun.cpp
F:/C++ Test/lintRun.cpp(3): error 753: (Info -- local class 'X' (line 3, file F:/C++ Test/lintRun.cpp) not referenced)
--- Global Wrap-up
error 900: (Note -- Successful completion, 7 messages produced)
Tool returned code: 7
2. 通常一个 VC 项目中包含多个 C 或 C++ 文件,有时需要同时对这一系列的文件进行 lint 检查,我们可以通过配置一个 pclint_project 来达到目的。
以下部分我还没有用到,留置。
和前面第一步中的方法基本一样,不过这里我们需要用到 unix 中的 find 等命令来查找当前目录下的 C 和 C++ 文件,然后再将它们送给 lint 程序处理,所以得先从 http://www.weihenstephan.de/~syring/win32/UnxUtils.zip 下载 UnxUtils.zip.
接着按下列步骤进行:
(i) 解压 UnxUtils.zip 至 c:/unix 下 , 可以看到 C:/unix/usr/local/wbin 有很多 unix 下的命令 , 等下会用到
(ii) 打开 VC6 , tools--->customize-->tools 新建一个名为 pclint_project 的项,只不过下面的 commands 和 arguments 内容不同。
commands: C:/unix/usr/local/wbin/find.exe
arguments: $(FileDir) -name *.c -o -name *.cpp | C:/unix/usr/local/wbin/xargs lint-nt -i"c:/unix/usr/local" -u c:/pclint/std.lnt c:/pclint/env-vc6.lnt
(自己注 4 :这里有一个小错误,如果不将 pc-lint 的安装路径写入系统 path 环境变量,那么上面设置后,在运行时会有错误:
C:/unix/usr/local/wbin/xargs: cannot fork Tool returned code: 1
原因,就在于上面的设置中, lint-nt 使用了相对路径,执行时找不到资源,所以改为绝对路径,一切就 ok 了 )
(iii)Use Output Window 打上勾, close 退出。好了,这时 VC tools 菜单下应该又多了一个 pclint_project 项了,你以后可以用它来对一个 VC 项目运行 lint 检查程序了 .
( 二 )SourceInsight 中集成 pclint 程序的方法 .
Windows 平台下也有好多人都喜欢用 SourceInsight 编辑 C/C++ 程序,如果将 pclint 集成到 SourceInsight 中,那就相当于给 SourceInsight 增加了一个 C/C++ 编译器 , 而且它的检查更严格,能发现一些编译器发现不了的问题,可以大大减少程序中潜伏的 BUG 。这样的话,相信更多人会喜欢 SourceInsight 这个工具了。
下面简要地介绍下 pclint 集成到 SourceInsight 中的方法
有了上面 VC 中集成 pclint 的经验 , 下面的事情就应该比较轻松了,
(a) 打开你的 SourceInsight, 选择 Options-->Custom Commands-->Add, 输入 pclint( 当然名字可以随便 ).
(b) Run 中输入 : c:/pclint/lint-nt -u c:/pclint/std.lnt c:/pclint/env-vc6.lnt %f
(c)Dir 留空,将 Iconic Window, Capture Output, Parse Links in OutPut, File,then Line 四项前打上勾。
(d) 然后点右侧 Menu--->Menu-->View--><end of menu>, 右侧 Insert, OK.
(e) 此时在 SourceInsight 中的 View 菜单下多了个 pclint 选项,可以用它来对单个 C/C++ 文件进行静态检查。
用类似的方法可以配置对一个 SourceInsight 工程文件的 lint 检查。
(a) 打开你的 SourceInsight, 选择 Options-->Custom Commands-->Add, 输入 pclint_project( 当然名字可以随便 ).
(b) Run 中输入 : C:/unix/usr/local/wbin/find.exe %d -name *.c -o -name *.cpp | C:/unix/usr/local/wbin/xargs lint-nt
-i"C:/unix/usr/local" -u c:/pclint/std.lnt c:/pclint/env-vc6.lnt
(c)Dir 留空,将 Iconic Window, Capture Output, Parse Links in OutPut, File,then Line 四项前打上勾。
(d) 然后点右侧 Menu--->Menu-->View--><end of menu>, 右侧 Insert, OK.
(e) 此时在 SourceInsight 中的 View 菜单下多了个 pclint_project 选项,可以用它来一个工程中的 C/C++ 文件进行静态检查。
本文主要对 pclint 集成到 VC 及 SourceInsight 环境中的方法根据本人安装和使用心得做了较详细介绍,希望对以前没使用过 pclint 的朋友们能有所帮助,不足之处还请多指正!
注: 关于库文件函数的实现与模块使用的一致性检查、 目前验证可以通过以下方式进行:
方法一:
将库文件( *.cpp/*.h )均复制到引用该库的模块的路径下。
方法二:
1 、建立一个 lnt 文件,名为 files.lnt 文件中保存的内容就是该模块,
及其使用的库的所有文件的全路经列表。例如:
E:/funtestC/fun.c
E:/funtestC/main.c
E:/libC/libMain.c
E:/libC/libC.h
(这个文件列表的创建可以写一段小程序实现,必要的信息都可以
从 mak 文件中获取。)
2 、将 files.lnt 的绝对路经写入 std.lnt 文件的末尾。