軟體品質保證工具 lint使用簡介發信人: SLEEPCAT(☆當豬愛上飼養員☆), 信區: Embedded. 本篇人氣: 77
標 題: lint使用簡介
發信站: 南京大學小百合站 (Thu Nov 6 10:27:08 2003)
LINT工具是一種軟體品質保證工具,許多國外的大型專業軟體公司,如微軟公司,都
把它作為程式檢查工具,在程式合入正試版本或交付測試之前一定要保證通過了LINT檢查
,他們要求軟體工程師在使用LINT時要開啟所有的編譯開關,如果一定要關閉某些開關,
那麼要給出關閉這些開關的正當理由。
可想而知,如果從我們編碼後第一次編譯器時就使用LINT來檢查程式,並且保證消
除所有的LINT警示,我們就不會遇到象今天這麼多的警示資訊。即使在今天,我們如果能
抽出一定的精力來消除程式中的LINT警示,以後再維持這種無警示狀態就是很容易的了。
我們程式品質的提高也是不言而喻的。
PC-LINT是GIMPEL SOFTWARE公司的產品,其中的內容是非常廣泛的,光是選項就有30
0多個,涉及到程式編譯及文法使用中的方方面面。本篇培訓材料旨在引導讀者入門,學會
PC-LINT的基本使用方法,起拋磚引玉的作用,能讓讀者從這裡起步繼續去研究如何嫻熟地
使用PC-LINT的各種選項,能讓它充分為我們的開發工作服務。
1.概述
如果要給LINT工具下一個形象點的定義,那就是:一種更加嚴格的編譯器。它不僅可
以象普通編譯器那樣檢查出一般的語法錯誤,還可以檢查出那些雖然完全合乎文法要求,
但很可能是潛在的、不易發現的錯誤。請看下面的例子:
1:
2:char *report( int m, int n, char *p )
3:{
4: int result;
5: char *temp;
6: long nm;
7: int i, k, kk;
8: char name[11] = "Joe Jakeson";
9:
10: nm = n * m;
11: temp = p == "" ? "null" : p;
12: for( i = 0; i 13: {
14: k++;
15: kk = i;
16: }
17:
18: if( k== 1 ) result = nm;
19: else if( kk > 0 ) result = 1;
20: else if( kk < 0 ) result = -1;
21:
22: if( m == result ) return( temp );
23: else return( name );
24:}
上面的代碼用一般的編譯器編譯是一段有效代碼,但是用PC-LINT編譯就會有幾個告
警。首先第8行向name數組賦值時丟掉了nul字元,第10行的乘法精度會失准,第11行的比
較有問題,第14行的變數k沒有初始化,第15行的kk可能沒有被初始化,第22行的result也
有可能沒有被初始化,第23行返回的是一個局部對象的地址。這段代碼在大部分編譯器下
是可以順利編譯通過的,繼續尋找其中的錯誤就要靠人工偵錯工具,如果程式很大,這將
是一項煩瑣的工作,沒有人可以保證能找出所有的這類問題,但PC-LINT只通過一次簡單的
編譯就可做到,顯然為我們節省了大量的開發時間。
下面就讓我們看看如何安裝使用PC-LINT。
2.如何安裝PC-LINT
PC-LINT的軟體的安裝過程比較複雜,選項較多,下面根據安裝過程,逐條說明每一步
的含義。
0)如果是zip檔案,將ZIP安裝檔案展開到目錄C:/lint.ins下,進入COMMAND PROMPT,先
進行目錄映射 subst g: c:/lint.ins,然後轉到G: , 執行install。其他步驟和下面的從
磁碟片安裝是一樣的。
1)在A:驅插入PC-LINT安裝盤,輸入A:/>install命令,進入開始安裝欄,按任意鍵繼續,
進入PC-LINT介紹欄,再按任意鍵繼續。
2)進入環境選擇欄,這一欄中有三個選項:
Windows NT/Windows 95
MS-DOS(DOS extended)
OS/2(32bit)
如果電腦安裝了WIN95、WIN97、WIN98或WINNT要選擇Windows NT/Windows 95,如果
只有DOS則選擇DOS。
3)進入安裝目錄選擇欄,它推薦的是C:/>LINT,如不想安裝在這個目錄下,可輸入自己想
要安裝的目錄,然後按斷行符號確認,如果要安裝的目錄不存在,它會提示為你建立這個目錄
。我們這裡選C:/>LINT
4)選擇安裝盤所在的磁碟機,我們這裡選A:
5)判斷是否要選擇多種編譯器或編譯庫的配置,如果要對不同編譯環境下的程式進行L
INT,則選YES,否則選NO。然後斷行符號確認。
6)這時看到一個編譯器列表,在這個表中選擇自己使用的編譯器,如果表中沒有自己使用
的編譯器,可選擇通用編譯器:Generic Compilers。按斷行符號確認。這個選項會體現在co-
xxx.lnt檔案中。
7)接著安裝程式會讓你選擇一個的記憶體模型,可以根據自己程式區和資料區的實際大小選
擇一個恰當的記憶體模型。如果CPU為32位68K系列,則要選擇:32-bit Flat Module。
記憶體模型的選項會體現在STD.LNT檔案中。
8)選完記憶體模型後,會看到一個庫類型的列表,在這裡選擇一個或多個編譯時間使用的庫。
這個選項會體現在LIB-xxx.LNT檔案中。
9)接著是讓你選擇為使用C++編程提出過重要建議的作者,選擇的某作者後,他提出的編
程建議方面的選項將被開啟。與作者選擇有關的選項會體現在AU-xxx.LNT檔案中。
10)下一步是設定包含檔案目錄。有兩種選項,第一種是使用環境變數INCLUDE,環境變數
在批次檔中設定,環境變數後每個目錄用分號隔開,例如可設成"INCLUDE=C:/MRI/M
CC68K;D:/LAP/SRC/INC"。第二種選項是使用-i選項,-i選項體現在STD.LNT檔案中,每個
目錄前以-I引導,目錄間以空格分隔,例如可設成"-IC:/MRI/MCC68K -ID:/LAP/SRC/INC
"。如果選擇使用-I選項,安裝程式會接著讓你輸入包含檔案所在的目錄。
11) 如果前面選擇了使用多個編譯環境,這裡將會問你是否選擇更多的編譯環境,如果選
YES,將會從第6步開使重複。如果選NO則會結束編譯器選擇。
12)接下來將會準備產生一個 反映全域編譯資訊顯示情況的選項檔案OPTIONS.LNT,該文
件的產生方式有兩種,一種是安裝程式對幾個核心選項逐一解釋並提問你是否取消該選項
,如果你選擇取消,則會體現在OPTIONS.LNT檔案中,具體體現方式是在該類資訊編碼前加
-e,後面第13~18步是逐一選擇核心選項的過程。如果選擇第二種選擇方式,安裝檔案會先
產生一個空的OPTIONS.LNT檔案,等你以後在實際應用時加入必要的選項。
13)是否關閉賦值時的布爾測試警示,如:if(a=f()){...
14)是否關閉賦值時的有符號量和無符號量間的不匹配警示,通常情況下,這種賦值不會
帶來問題,選擇關閉該警示資訊的同時,其他類型的有符號量和無符號量間混合操作的告
警仍然是開啟的。
15)當把一個整形量賦值給一個比它短的量時,後者會丟失精度,例如把一個INT量賦值給
給一個CHAR量。本步是讓你選擇是否關閉該類警示。
16)是否關閉左移帶符號量的警示。通常PC-LINT會對所有帶符號量的移動產生警示,但右
移一般是由不同的CPU來確定是否將符號位移入,左移一般是不會產生什麼問題的,所以可
以選擇關閉該警示。
17)在一個C函數被定義或聲明前調用它,並不總是會產生錯誤,在這裡可以選擇是否關閉
該警示選項。該選項對C++程式不起作用。
18)是否關閉"調用不存在的函數原型"警示。有些程式員不願遵守嚴格的函數原形定義
約定,但PC-LINT會在調用一個沒有定義的函數原型時產生一個警示,在這裡可以選擇關閉
該警示。
19)通過上面的步驟確定OPTIONS.LNT檔案的形式後,接著是選擇編譯環境。PC-LINT提供
了整合在多種開發環境中工作的功能,例如可整合在VC、BC、Source Insight中。假如我
們在這裡選擇Source Insight。選擇後安裝程式會繼續問你是否還選擇其它的環境,可根
據自己應用的實際情況選擇一種或多種開發環境。開發環境的選擇情況記錄在env-xxx.ln
t檔案中。
20)安裝程式會產生一個LIN.BAT檔案,該檔案是運行PC-LINT的批次檔,為了使該文
件能在任何路徑下運行,安裝程式提供了兩種方法供你選擇。第一種方法是讓你選擇把LI
N.BAT拷貝到任何一個PATH目錄下,在安裝結束運行LCOPY.BAT檔案時,會把LIN.BAT拷貝到
你指定的目錄。第二種方法是產生一個LSET.BAT檔案,在每次使用PC-LINT前先運行它來設
置路徑,或者把LSET.BAT檔案的內容拷貝到AUTOEXEC.BAT檔案中。
21)在安裝程式執行完後第一件事是在你安裝的目錄下執行LCOPY.BAT檔案。它會從安裝盤
拷貝將一些檔案拷貝到安裝目錄下,並根據你在安裝過程中的選擇來設定檔案中的參數。
3.LINT 一個C檔案
3.1用命令列方式進行LINT
如果使用LIN.BAT批次檔進行LINT,在LINT前要先看一下該批次檔中的內容,裡面
包含了LINT-NT命令和命令選項,可以根據自己的要求來修改、增減選項。我們看到,在這
個批命令中嵌套了一個std.lnt檔案,在std.lnt檔案中還嵌套了co.lnt、options.lnt和l
ib-stl.lnt檔案,原則上*.lnt檔案是可以無限制嵌套,該類檔案中一般都是了LINT的選項
,可通過修改這些檔案來修改LINT選項,選項是按照從左至右的順序執行的。可執行下面
命令列:
C:/abc/src>lin alpha.c beta.c gamma.c
通常對於由多個C模組組成的程式,最好先分別對每個C模組單元進行LINT檢查,做單元LI
NT時可如下運行:
C:/abs/src>lin -u alpha.c
其中-u是單元選項,使用-u後可以關閉一些檢查多模組時會產生的警示,例如"函數未被
使用"或"函數沒有定義"等。
也可以不使用LIN.BAT批次檔,而直接使用LINT命令。在DOS環境下LINT命令為LINT.E
XE,在Windows95/NT環境下為LINT-NT.EXE,在OS2環境下為LINT-OS2.EXE。直接使用LINT
命令要注意的一點是要在使用前預先設定LINT目錄所在路徑,最好的方法是把該路徑加在
AUTOEXEC.BAT檔案中。其它的使用方法與使用批次檔相同。例如:
C:/abs/src>lint-nt -ic:/lint/ std.lnt -os(_lint.tmp) *.c
3.2用開發環境進行LINT
也可以使用開發環境來執行LINT操作,一般開發環境都支援運行可執行檔,但不一定支
持運行批次檔,下面用Source Insight , Ultra Edit, MSVC 6.0 來舉例說明如何在
開發環境下進行LINT。
3.2.1 在Source Insight中整合
如果你在安裝過程中選定了使用某個開發環境,安裝程式會在你安裝的目錄下產生一個en
v-xxx.lnt的檔案,例如選擇了Source Insight就會有一個env-si.lnt檔案。用編輯器開啟
該檔案,在該檔案開始的注釋中說明了如何將PC-LINT功能整合在開發環境中,整合在Sou
rce Insight中的過程如下:
1)從Options菜單中選擇"Custom Commands"命令項。
2)在Name欄中輸入"PC-lint ",原則上這個名稱可以隨便起,只要你能搞清楚它的含義
就可以了。
3)在Run欄中輸入"c:/lint/lint-nt -u -ic:/lint std env-si %f"其中c:/lint是你P
C-LINT的安裝目錄。
4)在Output欄中選擇"Iconic Window"、"Capture Output"。
5)在Control欄中選擇"Save Files First"。
6)在Source Links in Output欄中選擇"Parse Links in Output"、"File,then Lin
e"。
7)在Pattern欄中輸入"^/([^ ]*/) /([0-9]+/)"。
8)點Add鍵加入該命令。如:
9)使用時,在Source Insight下開啟要LINT的檔案,開啟Options菜單中的"Custom Com
mands"命令項,在"Command"欄中選擇"PC-lint unit check"命令運行即可。
注意到我的Run一欄的參數和上面的提示不一樣,其實我的其他古怪參數都放到c:/lint/s
td.lnt中了。請注意,不論你怎樣配置參數一定不要忘記了將si-env.lnt包含在你的配置
檔案裡,否則就無法進行錯誤資訊和程式的自動對應了。
為了使用方便,你還可以配置一下Menu按鈕,將它加到系統菜0單裡,這屬於一般性的
Source Insight應用,筆者就不在此贅述了。
第二筆者在NT中使用Source Insight時,好象整合不了,原因暫時不明了。上面的例子在
WIN 95下測試成功。
如果要修改LINT選項,可直接在Run欄中修改,也可專門編輯一個*.lnt檔案放在c:/lint目
錄下,並將該檔案名稱加入Run欄中,和命令列方式是一樣的。
3.2.2在Ultra Editor中整合
選取 Menu | Advanced | Tool Configuration ... , 顯示如:
1)點按"Insert",
2)在command line:中填寫:c:/lint/lint-nt c:/lint/std.lnt %f
3)在Menu Item中填寫:PC-LINT
4)在Command Output中選擇: (x) Output to List Box 和 (x) Capture Output
5)點按"OK"
的配置筆者在UE6.0 / NT 4.0 下測試成功。
3.2.3 在MSVC 6.0中整合
基本原理是一樣的:
1)選取 menu | tools | customize.....
2)選取 Tools Tab:
3)點按主對話方塊上方的虛線小方框 New a tool item
4)輸入 name: PC-LINT
5)輸入 Command: c:/lint/lint-nt.exe
6)輸入 Arguments: c:/lint/std.lnt $(FilePath)
7) 選擇 (x) Use Output Window
8)Close
完成後,在tools菜單下就會有一項PC-LINT選項。
下面是筆者在VC6 / Win NT 4.0 的情況下的TOOL配置圖:
3.3LINT選項
LINT選項可以放在注釋中,例如:
/*lint option1 option2 ... optional commentary */
//lint option1 option2 ... optional commentary
選項間要以空格分開,lint命令一定要小寫,並且緊跟在/*或//後面,不能有空格。如果
選項由類似於操作符和運算元的部分組成,例如-esym(534, printf, scanf, operat or
new),其中最後一個選項是operator new,那麼在operator和new中間只能有一個空
格。
選項還可以放在宏定義中,例如:
#define DIVZERO(x) /*lint -save -e54 */ ((x) /o) /*lint -restore */
LINT的選項很多共有300多種,大體可分為以下幾類:
1)錯誤資訊禁止選項
該類選項是用于禁止產生某類錯誤資訊的選項,最常用的是-e和+e,-e是禁止產生某類錯
誤資訊,+e是恢複產生某類錯誤資訊。運行lint目錄下的msg.exe可以得到msg.txt檔案,
這個長達5000行的檔案包含了所有的錯誤資訊號和解釋。
-w 對於所有大於層級的警示資訊都不顯示。
-wlib()對於所有大於層級的關於庫函數數的警示資訊都不顯示。我們可以用-wlib(0)來屏
蔽所有的庫函數的警示資訊,-wlib(1)只顯示庫函數中的句法錯誤。
-esym(#,) 可以屏蔽對於特定符號的某警示資訊。
2)變數類型大小選項
不同的目標機、編譯系統變數類型的的大小(如短整形變數、整形變數等)會有所不同,
該類選項用於為目標機設定變數類型的大小。由於預設的設定與大部分的編譯器是匹配的
,這些專門的設定通常情況下是不需要的,只在特別的目標機結構中才用。例如一個M680
00目標機,它的int類型和指標類型通常是32bit的,這時你應該使用選項:-si4
-sp4。這些尺寸參數的當前值可以通過help屏來獲得,例如可以輸入以下命令列:
lin -si4 -sp4 ?
3)冗長資訊選項
冗長資訊指的是LINT過程中產生的一些與編譯過程有關的資訊,而不是真正的警示資訊、
錯誤資訊等。是否產生這些資訊可以通過-v和+v選項來決定。+v是產生這些資訊,-v是關
閉這些資訊,這組選項中除+v外,其它所有選項都可以關閉+v選項。
4)標記選項
以+f、++f、-f和--f開頭的選項是標記選項。他們的邏輯含義分別如下:
+f...:通過把標誌置為1而把它置為ON
-f...:通過把標誌置為0而把它置為OFF
++f...:標誌增1
--f...:標誌減1
後面兩個用於你想在局部把一個標誌置為ON的情況,而不影響全域設定。例如你可以這樣
使用:
/*lint ++flb */
int printf( );
/*lint --flb */
標記選項的種類很多,基本含義是用於開啟或關閉某類文法情況使用,例如允許使用縮寫
結構體名稱,允許使用無名聯合體,把所有模組當作C++編譯等。
5)訊息顯示選項
訊息顯示選項用於定義訊息輸出格式。主要有訊息高度選項、訊息寬度選項、訊息格式選
項等。
6)其它選項
其它選項中的種類很多,各種類間差異很大,在這裡就不一一介紹了,建議大家看一看《
PC-LINT》一書,第五章有對每種選項的詳細說明。lint本身也有一些說明資訊, lint-n
t 2> lint.txt 然後狂按幾個斷行符號就可以產生一個lint選項的說明檔案。
4.LINT一個工程下的多個C檔案
4.1為何要LINT多個C檔案
在程式編碼初期,我們關心的可能只是單個C模組種中的文法問題,等到編程後期,對於由
多個C模組組成的程式,我們希望瞭解當把多個模組串連在一起後是否還有存在於模組間的
文法問題。這時編譯器雖然能給出一些警示,但PC-LINT的串連能給出更多的警示。還有當
我們能保證其中的幾個模組相對穩定,而另外幾個模組仍有問題時可以先將幾個穩定的模
塊編譯串連成一個目標檔案,檔案每次修改完成後先單獨編譯,然後串連入總的目標檔案
。
4.2如何LINT一個工程下的多個C檔案
象我們平時使用的編譯工具一樣,PC-LINT在編譯串連多個C檔案時也會先把每個C檔案編譯
產生中間的目標檔案*.lob,然後再將所有的LOB檔案串連在一起。LOB是Lint Object Mod
ule的縮寫。這個檔案中包含了一個C或C++模組的所有外部資訊。產生LOB檔案時有三種選
項要注意:第一種是-u,如果要LINT產生LOB檔案,就一定要加-u選項;第二種是-zero或
-zero(500)選項,為了保證LOB檔案在模組存在錯誤的情況下也能產生,就一定要加這個選
項;第三種是-oo[(filename)],filename是產生的LOB檔案的名稱,在-oo後面,可加,也
可不加,如不加,則LOB檔案名稱與原C模組的名稱相同,例如:
lint -u alpha.c -oo(a1)
產生的LOB檔案名稱為:a1.lob
lint -u alpha.c -oo
產生的LOB檔案名稱為:alpha.lob
LINT一個工程下的多個C模組,在使用者的來源程式目錄下一般需要三個檔案: 一個選項檔案
(*.lnt)、一個批次檔(*.bat)和一個MAKEFILE檔案(*.mak)。下面一一講述如何
製作這些檔案。
1)選項檔案(*.lnt)
選項檔案在前面也提到過,你可以把你LINT每個C檔案時時用到的所有公用選項羅列在該文
件中,選項生效的順序按照從左至右,從上到下的原則。該類檔案可以層層嵌套,嵌套的
層數沒有限制。例如make.lnt檔案:
-iC:/lint
std.lnt
+os(temp)
-e46
+vm
-zero
2)批次檔(*.bat)
製作批次檔時要注意要在該檔案中調用TCMAKE.EXE檔案和MAKEFILE檔案,例如lintma
ke.mak檔案:
@echo Lint Making 'makelap':
tcmake -flintmake.mak
@echo End of making
3)MAKEFILE檔案(*.mak)
MAKEFILE使用的TCMAKE的文法,和我們平時開發編譯時間使用的MAKEFILE檔案文法格式一樣
,例如下面的lintmake.mak檔案:
MCCPATH = c:/mcc68k
OPTION = -u make.lnt -oo
GLOBLE = os.h l2lap.h
mail_depend = $(GLOBLE) q931.h mail.h
lapmain_depend = $(GLOBLE) l1pubdef.h q931.h mail.h
lapos_depend = $(GLOBLE)
fhdlc1_depend = $(GLOBLE) cpuhdlc.h bd_prar.h q931.h
OBJ = mail.lob lapmain.lob lapos.lob fhdlc1.lob
project.lob : $(OBJ)
lint-nt make.lnt -e768 -e769 *.lob
mail.lob: mail.c $(mail_depend)
lint-nt $(OPTION) mail.c
lapmain.lob: lapmain.c $(lapmain_depend)
lint-nt $(OPTION) lapmain.c
lapos.lob: lapos.c $(lapos_depend)
lint-nt $(OPTION) lapos.c
fhdlc1.lob: fhdlc1.c $(fhdlc1_depend)
lint-nt $(OPTION) fhdlc1.c
4.3簡單的LINT多個檔案
假設我們的工程不複雜,我們可以負擔起每次都將所有的檔案都lint一遍的開銷,也可以
不使用上面的正規用法。筆者在實踐中發現,將所有的*.c檔案放在一個lint命令中,同樣
能完成lint整個工程的目的。
如:
lint-nt c:/lint/std.lnt AllMySource.lnt
在AllMySource.lnt中包括你的工程中的所有源檔案:
a1.c
a2.c
a3.c
需要注意的是,在std.lnt檔案中就不需要-u選項了。因為我們已經提供了所有的資訊