linux pc-lint

今天终于把pclint环境搭建好了,可以在windows直接使用sis写代码并用pclint检查代码了。下面介绍下: 
<转载自: hi.baidu.com/qiupingwu>
1. PC-Lint 是什么?
   如果你真的不知道它是什么? 那么请私下询问 Google, 但千万不要声张:-).
   简单而言, PC-Lint 是 Gimpel Software 公司出品的一个很牛<注1>的软件, 你可以叫它吹毛求疵器, 因为它能够做比编译器严格得多的(包括但不限于)语法检查.

   事实上这个工具有两个版本: 一个叫 PC-Lint, 是针对 PC 机的 (主要是对付 Windows, MS-DOS, OS/2 等系统), 以可执行文件形式发布; 另一个叫 FlexeLint, 是针对其它系统的 (比如 Linux), 采用源码方式发布.

   由于很少见到 FlexeLint, 本文仅就 PC-Lint 的使用进行介绍. 目前在官方网上出现的最新版本是 9.0, 但同样不易获得, 所以本文只介绍 PC-Lint8.0. 我们将采用变通的方法实现对 Linux 系统下的代码检查.

2. 使用环境
   正如前面所说, PC-Lint 本来只当游弋于 Windows, OS/2 之上, 但由于 C 的标准化做得比较好, 所以稍作变通, PC-Lint 是完全有能力对付那些针对 Linux 系统的代码的.
   除了操作系统环境, 要想使用得顺手, 还应该把 PC-Lint 和编译/编辑环境结合起来. 现在 PC-Lint 已经能很好地和大部分主流编译/编辑器整合, 使用起来非常方便.

   下文将就这两个方面进行讨论.

2.1. 配合 Linux 的使用
   在 Linux 系统下, 通常使用 GCC 作为 C 代码的编译器. 为了使 PC-Lint 能有效地检查针对 Linux 的代码, 应该为它选定正确的头 (.h) 文件. 通常这些文件都放在 /usr/include 和 /usr/ /include 目录下.
   由于 PC-Lint 不能在 Linux 系统上运行, 所以要把上面两个目录映射 (作磁盘映射) 到 Windows 系统, 这样目录就变成了 Z< 3>:/usr/include 和 Z:/usr//include. 也可以把 Linux 的头文件直接 COPY 到 Windows 系统中, 这时系统会提示文件重名 , 但这些文件一般用不到, 直接覆盖就行.
(我是直接拷贝到windows下c:/pclint/usr下,不过没有拷贝/usr//include)

   为了让 PC-Lint 能认出这两个目录, 要在 std.lnt 文件中增加
    -iZ:/usr/include
    -iZ:/usr/3.4.3/include
两行.

   另外由于 PC-Lint 是针对 Windows 设计的, 会抱怨 Linux 某些头文件不正确. 由于我们不提倡自己修改标准文件, 因此干脆让 PC-Lint 暂时失声好了. 这可以通过在 options.lnt 文件增加下面几行实现:
    -e716 // allow use while (1)
    // bug in syslog.h, it define __need_va_list_ macro
     -efile(537,stdarg.h)
     -emacro(530,va_start) // do not init first parameter

修改 options.lnt 文件, 使用 gnu 检查规则, 即应该有如下一行:
    c:/pclint/lnt/co-gnu3.lnt
假设 PC-Lint 安装在 C:/pclint 目录下.

   配置好这些, 在 Windows 上检查 Linux 代码就应该比较顺手了.

2.2. 配合 SourceInsight 的使用
   在 SourceInsight 中可以新建一个命令. 通过 Custom Commands 窗口, 在其中的 Command 中填入命令名 (比如是 lint), 再在 Run 中 填入
    C:/pclint/LINT-NT.EXE -u -ic:/pclint/lnt std.lnt env-si %f
再在 Pattern 框里填写
    ^/(.*/.[a-zA-Z]+/)/w/([0-9]+/).*
然后点击 Add 按钮即可.

   此后要对 C 文件进行检查时, 直接执行该命令即可.

3. 配置
   上面的配置都是一成不变的, 配置好之后, 基本上都不需要改动了. 但对于不同的项目, 还有一些针对项目本身的特殊配置. 在这一小节, 将对针对特定项目的配置进行说明.

   首先, 每个项目都有各自的头文件, 因此需要在 std.lnt 指定项目的头文件目录. 格式如下:
    -i<头文件目录>
例如:
    -iZ:/sw-new/src/license

   另外, 如果项目有些目录是第三方提供的, 或者我们不关注其中的警告, 则可以把这些目录指定为库目录. 格式如下:
    +libdir(<库目录1>,<库目录2>,...)
例如:
    +libdir(z:/usr/include,z:/usr/3.4.3/include,z:/mysql/include)
   对于以前没检查过的项目, 第一次使用 PC-Lint 检查时, 可能会出现很多警告和错误. 为了不至于使有用的错误掩埋于警告之中, 可以在 options.lnt 中配置全局的检查等级, 使其只显示严重的错误. 方法为:
    -w<等级数>
其中等级数越大, 输入的警告错误就越多. 建议逐渐加大此数, 分步消除错误和警告. 比如先从
    -w1
开始.
   还可以使用
    -e<错误号>
暂时屏蔽对某个错误的检查.

4. 避免无病呻吟
   也会有这样的情况: 对某些代码, 你确认----想想你的论据是否充分, 别急于下此结论哦:-)----没有问题, 但 PC-Lint 却在每次检查时都抱怨, 这时可以通过在代码作特殊注释让 PC-Lint 跳过某些检查.
   PC-Lint 提供了大量的特殊注释, 可以把这些注释加到代码中, 对代码的每个段落、每一行甚至每个表达式进
行精细的检查控制.

   下面列举出一些常用的选项, 更多选项可参数 PC-Lint 的使用手册. 注意这些选项都要放到 C 代码的注释中, 且格式为 /*lint */, 其中 lint 必须紧接在 /* 后面出现, 表示选项, 选项后留一个空格, 然后才是 */.
   1). -e(#[,#]...)   仅对下一个表达式有效,
   a = /*lint -e(413) */ *(char *)0;

   a = /*lint -save -e413 */ *(char *)0
   /*lint -restore */;
是等价的.

   2) . --e(#[,#]...) 对其所在的整个表达式有效,
   a = /*lint --e(413) */ *(int *)0 + *(char *)0;
将阻止两个 413 信息的输出, 而使用 -e(413) 则只阻止第一个 413 输出.

   3) . -e{#[,#]...} 对下一个语句或者声明有效. 这种用法的影响范围很灵活: 当其在函数之前时, 对整个函数有效; 在某个赋值语句前, 对该个赋值语句有效; 在 if while 等语句前对这整个语句段有效.

   4) . --e{#[,#]...} 对于其所处的 {} 号内的整个代码体有效, 这包括函数体, 类, 结构等等. 如果不处于任何 {} 号内, 则对整个文件有效 (当然, 是指从 --e{} 出现的地方至文件结束).

   5) . !e# 仅对其所在行有效.
   6) . -esym(#,sym[,sym]) 对指定的符号屏蔽警告.

5. 常见错误处理
   下面列举一些常见的错误, 及处理方法, 供参考:
   525 提示错误缩进, 原因是代码中空格和 TAB 键混合使用了, PC-Lint 认为代码的缩进与代码逻辑不符合. 把代码统一改成使用空格即可< 5>.

   715 符号未被引用, 原因是在函数中的某个调用参数或者局部变量没被使用. 对局部变量可以直接去掉, 对于参数则把其放到 if 语句中即可.
   740 提示不寻常的类型转换, 通常发生在指针类型转换时, 转换前后指针所指类型空间大小不一致时. 可通过在转换前加
   /*lint -e(740) */
的方式屏蔽此警告.

   818 函数的指针参数在函数内部没被修改, 提示参数定义为常量指针. 按照提示在指针参数前加上 const 修饰符就可以了. 但是似乎 PC-Lint 在处理这个问题的时候有 BUG, 有时即使加了 const 修饰符还是会继续提示此警告, 此时就应该在对这个函数这个指针参数屏蔽 818 警告, 方法为在函数开始前添加
   /*lint -esym(818, pointer) */
在函数结束后添加
   /*lint +esym(818, pointer) */
   827 不可到达的代码, 原因是在 while (1)/for (;;) 后还有代码, 但这些代码永远无法执行到. 解决方法是在不能执行到的代码行前加上
   /*lint -unreachable */
   <1> 并非因为是在牛年出品, 而是因为它确实本来就很牛.
   <2> 这里是指当前使用的 GCC 版本, 比如 3.4.3.
   <3> 假设映射到 Z 盘.
   <4> 原因是 Linux 文件名区分大小写, 而 Windows 不区分.
   <5> 这种工作可以由 indent 代劳, 相信它, 它能做得很好.

你可能感兴趣的:(C/C++编程)