到底需不需要編譯器之外的獨立的靜态代碼檢查工具呢?這個問題'仁者見仁,智者見智'。但是有一個結論我想大家都會認可,那就是越是在開發周期早期發現的
Bug,修複它所付出的代價就越小。而像lint這樣的靜态代碼檢查程式恰恰是讓Bug在早期階段'顯露原型'的絕佳工具,而追求'lint-
clean'[注1]境界的代碼也向來是專家級程式員的嗜好。别忘了在'C專家程式設計'一書中曾經提到Sun
OS的核心一直是保持'lint-clean'狀态的,這就是榜樣!還等什麼?趕快學呀!^_^
有人抱怨'不敢用lint工具,
太多的Warnings把快螢幕都淹沒了!',不過高手一般不這麼想,他會細心琢磨這些Warnings背後的'暗示',并和lint工具溝通,利用
lint工具提供的互動方法屏蔽掉一些經過分析認為不能成為錯誤的Warnings。久而久之,高手本身就成了一個lint程式,就能夠很快的用肉眼發現
代碼中的問題,并指出問題所在,如何解決!他還能告知如何嵌入一些Annotations進而避免讓lint程式産生不必要的Warnings,這時這位
高手對語言和程式的了解就又提高了一個檔次了。其實使用ling工具不僅僅是為了提早發現程式中的Bug,其使用過程有助于你加深對程式的認識和了解。的
确事實就是這樣。
Splint就是一款強大而且應用廣泛的開源lint工具。它的強大的代碼檢查能力固
然讓人稱道,但是讓我更欣賞的卻是它提供的'Annotations'機制。
Splint可以讓程式員在自己的代碼中嵌入相應的Anotations,這些Anotations作為Splint分析代碼時的輸入以幫助Splint
産生對程式員更有用的資訊。下面是一些Splint的使用入門,更多詳細資訊請檢視'Splint
manual'。
1、最簡單的Splint使用方法
>> splint *.c
2、Splint輸出Warnings的基本格式
<file>:<line>[,<column>]: message
[hint]
<file>:<line>,<column>: extra location information, if appropriate
我們可以使用'+/-<flags>'來自定義其輸出格式,如'splint -showcol
*c',則Splint不會在輸出資訊中顯示'列'資訊。
3、使用flags控制splint的檢查範圍和輸出格式
'+<flag>' -- 表明某個flag處于打開狀态,如'+unixlib';
'-<flag>' -- 表明某個flag處于關閉狀态,如'-weak';
4、使用.splintrc環境檔案
如果不想每次使用splint的時候都手工輸入一堆'+/-<flags>',那麼你可以把這些'+/-<flags>'預先寫
到.splintrc檔案中,當splint執行的時候它會自動加上這些flags的。預設的flags設定在'~/splintrc'檔案中,但是如果
一旦splint的目前工作路徑下也有.splintrc檔案,那麼這個.splintrc檔案中的flag設定會覆寫'~/splintrc'中的
flags設定,但是指令行中的flags設定是具備最高優先級的,它會覆寫前面提到的任何一個檔案中的flags設定。
5、使用Annotations
對于'Annotations'的作用,Java程式員并不陌生,但是C程式員則對這個不是那麼了解。C代碼中的Annotations用來指導Splint生成恰當的代碼檢查報告。下面這個例子對比使用和不使用Annotations,Splint的輸出的差别:
/* testlint.c */
void foo1() {
/*@unused@*/int *p = NULL;
}
void foo2() {
int *p = NULL;
splint testlint.c
Splint 3.1.1 --- 28 Apr 2003
testlint.c: (in function foo2)
testlint.c:6:7: Variable p declared but not used
A variable is declared but never used. Use /*@unused@*/ in front of
declaration to suppress message. (Use -varuse to inhibit warning)
Finished checking --- 1 code warning
可以看出沒使用Annotation的函數foo2被給出Warning了。Splint的Annotations繁多,我們在平時做lint時可以多多接觸。