如何使用开源静态代码检测工具Splint?
如何使用开源静态代码检测工具Splint?
如果想用一个有效的工具察看C/C++源代码中的错误,遗漏,不确定的构建过程,以及移植问题等等,你应该来看看Lint。可以把Lint当成一个编译器,除了不产生代码之外,对于错误和警告的报告来说已经非常足够了。
通常,一个C/C++的编译器假设程序是正确的,而Lint恰恰相反,因此它优于编译器执行的一般性检查。Lint还可以贯穿多个文件来执行它的错误检查和代码分析,这是编译器做不到的。
下面是Lint能够检查的部分错误列表。如果你幸运的话,你的编译器也可以检查出其中的一些,但不会使全部。
可能的空指针
在释放内存之后使用了该指针
赋值次序问题
拼写错误
被零除
失败case 语句 (遗漏了break语句)
不可移植的代码
宏定义参数没用使用圆括号
符号的丢失
异常的表达式
变量没有初始化
可疑的判断语句(例如, if (x = 0))
printf/scanf 的格式检查
现有的 Lint 程序
这是两个流行的Lint 程序:
PC-lint是一个由Gimpel Software提供的支持C/C++的商用程序。
Splint (原来的 LCLint) 是一个GNU免费授权的 Lint程序,但是只支持C不支持C++.
Lint 的运行
运行 Lint 跟运行一个正常的编译器一样,只要把直接加入的makefile 中就可以了。在便以前后都可以运行它。
尽管在编译前运行它看起来更有意义,但有时在成功变以后执行更有价值。这意味着,编译器报告了例如键盘输入错误等各种错误,而Lint在已编译的代码上给与更多的检查。
当使用Lint的时候,不要为他报告的错误及告警信息的数目而惊慌失措。通过学习怎样控制Lint的输出你就不会着这样了。
简单的说
lint是检查你的c文件有没有语法错误的
编译器也可以检查
不过lint检查的更多
如下面这些错误 编译器多数不会报错 最多只会出warning 有很多也不会出warning 因为它们符合语法 只是得到的结果与你想得到的结果不一样
可能的空指针
在释放内存之后使用了该指针
赋值次序问题
拼写错误
被零除
失败case 语句 (遗漏了break语句)
不可移植的代码
宏定义参数没用使用圆括号
符号的丢失
异常的表达式
变量没有初始化
可疑的判断语句(例如, if (x = 0)) ========特别是这个 最危险的地方而编译器不会报错
printf/scanf 的格式检查 ======这个也危险
使用lint可以为自己的代码减少这样的错误
输出控制
通过一系列方法可以控制和校准Lint的输出:
配置选项:通过命令行参数或一个配置文件,你能发现有上百个选项可以优化输出。
代码注释:在你的代码中可以为Lint加入特殊的注释。这样可以非常好的控制你希望检查的代码,例如,这里有一个返回NULL指针的函数, Splint可以通过下面的注释 /*@null@*/ 来识别:
/*@null@*/ void *test(void)
{
// a function that returns NULL!
return NULL;
}
这有两个目的: 1)防止Splint 为这个返回Null指针的函数高景,2)保证Splint 检查任何调用该函数的代码中使用该函数的返回指针是有效的。 (虽然Splint和PC-lint 有着不同的代码注释约定,但基本原理是相同的。)
同样对这个问题而言,使用全局的配置选项“-nullret”可以屏蔽掉所有的null指针检查,从而不用增加那些柱石,缺点是由你的代码将被检查的不彻底。然而,这种方法有时候是必需的,尤其是在某些现存的代码上第一次使用Lint。
缓慢启动
你怎样启动Lint呢?最好在一个项目中尽早地开始使用Lint, 尤其是在你已经生成了大量的未检查代码之前。如果没这样做,将会使效率降低。
打开编译器中的严格告警,一旦你的代码没有被编译器发现任何告警,启动Lint。然后逐渐地增加Lint测试的严格性,同时在需要的地方增加代码注释。有效的使用Lint需要时间,但这种努力是值得的。