版權聲明:本文爲博主原創文章,未經博主容許不得轉載。 https://blog.csdn.net/u011012932/article/details/52778149shell
簡述
Cppcheck 是一種 C/C++ 代碼缺陷靜態檢查工具。不一樣於 C/C++ 編譯器及不少其它分析工具,它不檢查代碼中的語法錯誤。Cppcheck 只檢查編譯器檢查不出來的 bug 類型,其目的是檢查代碼中真正的錯誤(即:零誤報)。數據庫
| 版權聲明:一去、二三裏,未經博主容許不得轉載。編程
介紹
支持的代碼和平臺:json
- 能夠檢查非標準代碼,包括不一樣的編譯器擴展、內聯彙編代碼等。
- Cppcheck 應該被處理最新 C++ 標準的任何 C++ 編譯器所編譯。
- Cppcheck 應該在任何有足夠 CPU 和內存的平臺上工做。
要知道 Cppcheck 有限制,Cppcheck 不多在報告錯誤方面出錯,但有不少 bug,它不能檢測。markdown
經過仔細測試軟件,你會發現軟件中有更多的 bug,而不是使用 Cppcheck。但 Cppcheck 仍能夠檢測到在測試和評估軟件時錯過的一些 bug。多線程
開始使用
第一個測試程序
這裏有一段簡單的代碼:函數
int main() { char a[10]; a[10] = 0; return 0; }
- 1
- 2
- 3
- 4
- 5
- 6
將代碼保存進 file.c 文件中,執行:工具
cppcheck file.c
- 1
注意:執行此命令前,須要將 cppcheck.exe 所在路徑添加至環境變量 PATH 中。性能
這時,將會從 cppcheck 中輸出:測試
Checking file.c …
[file.c:4]: (error) Array ‘a[10]’ accessed at index 10, which is out of bounds.
檢查文件夾中的全部文件
一般一個項目會有許多源文件,若是須要同時檢查,Cppcheck 能夠檢查文件夾中的全部文件:
cppcheck path
- 1
若是 path 是一個文件夾,cppcheck 將遞歸檢查這個文件夾中的全部源文件。
Checking path/file1.cpp…
1/2 files checked 50% done
Checking path/file2.cpp…
2/2 files checked 100% done
手動檢查文件或使用項目文件
使用 Cppcheck 能夠手動檢查文件,經過指定文件/文件夾來檢查和設置,或者可使用一個工程文件(cmake/visual studio)。
使用項目文件更快,由於它只須要很是少的配置。
手動檢查文件能夠更好的控制分析。
不必定哪一種方法會有最好的結果,建議嘗試一下,可能會獲得不一樣的結果,發現大多數 bug 須要使用這兩種方法。
檢查時排除某個文件或文件夾
排除一個文件或文件夾有兩個選項,第一個選項是隻提供你想檢查的路徑和文件:
cppcheck src/a src/b
- 1
全部位於 src/a 和 src/b 下的文件都會被檢查。
方式二:使用 -i
選項
這時,將會忽略指定的文件/文件夾,使用下面命令在 src/c 將不會被檢查:
cppcheck -isrc/c src
- 1
嚴重性
可能的嚴重性消息有:
-
錯誤
當發現 bug 時使用 -
警告
關於防護性編程,以防止 bug 的建議 -
風格警告
風格有關問題的代碼清理(未使用的函數、冗餘代碼、常量性等等) -
可移植性警告
可移植性警告。64 位的可移植性,代碼可能在不一樣的編譯器中運行結果不一樣。 -
性能警告
建議使代碼更快。這些建議只是基於常識,即便修復這些消息,也不肯定會獲得任何可測量的性能提高。 -
信息消息
配置問題,建議在配置期間僅啓用這些。
啓用消息
默認狀況下,只顯示錯誤消息,能夠經過 --enable
命令啓用更多檢查。
啓用警告消息:
cppcheck --enable=warning file.c
- 1
啓用性能消息:
cppcheck --enable=performance file.c
- 1
啓用信息消息:
cppcheck --enable=information file.c
- 1
因爲歷史緣由 --enable=style
能夠啓用警告、性能、可移植性和樣式信息。當使用舊 XML 格式時,這些都由 style 表示:
cppcheck --enable=style file.c
- 1
啓用警告和性能消息:
cppcheck --enable=warning,performance file.c
- 1
啓用 unusedFunction 檢查。這不能經過 --enable=style
啓用,由於不會在庫中正常工做。
cppcheck --enable=unusedFunction file.c
- 1
啓用全部消息:
cppcheck --enable=all
- 1
不肯定消息
默認狀況下,若是肯定,Cppcheck 只顯示錯誤消息。若是使用 --inconclusive
,當分析不肯定時,也會寫錯誤消息。
cppcheck --inconclusive path
- 1
這固然會致使錯誤的警告,即便在沒有 bug 的狀況下,也可能會報 bug。若是能夠接受錯誤的警告,可使用此命令。
保存結果到文件中
不少時候,會但願將結果保存在一個文件中,可使用 shell 的管道重定向錯誤輸出到一個文件:
cppcheck file.c 2> err.txt
- 1
多線程檢查
選項 -j
用於指定須要使用的線程數,例如,使用 4 個線程檢查文件夾中的文件:
cppcheck -j 4 path
- 1
注意:這將禁用 unusedFunction 檢查。
平臺
應該使用一個與你的目標匹配的平臺配置。
默認狀況下,若是代碼在本地編譯和執行,Cppcheck 會使用本地平臺配置。
Cppcheck 具備用於 Unix 和 Windows 目標的內置配置,能夠輕鬆地使用這些 --platform
命令行標誌。
還能夠在 XML 文件中建立本身的自定義平臺配置。這裏有一個例子:
<?xml version="1"?> <platform> <char_bit>8</char_bit> <default-sign>signed</default-sign> <sizeof> <short>2</short> <int>4</int> <long>4</long> <long-long>8</long-long> <float>4</float> <double>8</double> <long-double>12</long-double> <pointer>4</pointer> <size_t>4</size_t> <wchar_t>2</wchar_t> </sizeof> </platform>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
項目
當使用 CMake 或 Visual Studio 時,可使用 --project
來分析項目。
它會給你快速和簡單的結果,不須要作太多的配置。但很難說這是否將會給你最好的結果,建議試一試它,並嘗試不使用 --project
分析源代碼,看哪一個選項更適合。
CMake
Cppcheck 能夠理解編譯數據庫,能夠用 CMake 生成這些。
例如:
$ cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
- 1
文件 compile_commands.json 在當前文件夾中建立。
如今像這樣運行 Cppcheck:
$ cppcheck --project=compile_commands.json
- 1
Visual Studio
能夠對單個項目文件(*.vcxproj
)或整個解決方案(*.sln
)運行 Cppcheck。
在整個解決方案上運行 cppcheck:
$ cppcheck --project=foobar.sln
- 1
在單個項目文件上運行 cppcheck:
$ cppcheck --project=foobar.vcxproj
- 1
注意:還有一個 Visual Studio 插件,容許在 Visual Studio 中運行 cppcheck。
預處理器設置
若是使用 --project
,那麼 Cppcheck 將使用項目文件中的預處理器設置。
不然,可能須要配置包含路徑,定義等。
定義
這有一個文件,有兩個配置(定義和沒定義 A):
#ifdef A x = y; #else x = z; #endif
- 1
- 2
- 3
- 4
- 5
默認狀況下,Cppcheck 將檢查全部預處理器配置(除了那些具備 #error 的配置),因此上述代碼將被分析在當 A 定義和不定義的狀況下。
可使用 -D
更改。當使用 -D
時,cppcheck 將默認只檢查給定的配置,不會檢查其它,這就是編譯器的工做原理。可是可使用 --force
或 --max-configs
來覆蓋配置數量。
檢查全部配置:
cppcheck file.c
- 1
只檢查配置 A:
cppcheck -DA file.c
- 1
當定義宏 A 時,檢查全部配置:
cppcheck -DA --force file.c
- 1
另外一個有用的標誌多是 -U
,它未定義符號。 用法示例:
cppcheck -UX file.c
- 1
這意味着 X 沒有定義,Cppcheck 不會檢查當定義 X 時會發生什麼。
XML 輸出
Cppcheck 能夠生成 XML 格式的輸出。有一箇舊的 XML 格式(version 1)和一個新的 XML 格式(version 2)。若是能夠,請使用新版本。
舊版本保持向後兼容性。它不會改變,但有一天可能會被刪除。使用 --xml
支持這種格式。
新版本修復一些舊格式的問題。新格式可能會在 cppcheck 的將來版本中更新,並帶有新的屬性和元素。用於檢查文件並以新的 XML 格式輸出錯誤的示例命令:
cppcheck --xml-version=2 file.cpp
- 1
這是一個 version 2 示例:
<?xml version="1.0" encoding="UTF-8"?> <results version="2"> <cppcheck version="1.66"> <errors> <error id="someError" severity="error" msg="short error text" verbose="long error text" inconclusive="true" cwe="312"> <location file0="file.c" file="file.h" line="1"/> </error> </errors> </results>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
<error>
元素
每一個錯誤都在 <error>
元素中,屬性:
-
id
錯誤的 id,這些都是有效的符號名稱。 -
severity
error、warning、style、performance、portability、information 中的任何一個。 -
msg
短格式的錯誤消息 -
verbose
長格式的錯誤消息 -
inconclusive
此屬性僅在消息不肯定時使用 -
cwe
消息的 CWE ID,此屬性僅在消息的 CWE ID 已知時使用。
<location>
元素
<location>
元素列出全部錯誤相關位置,首先列出主要位置。
屬性:
-
file
文件名,相對路徑和絕對路徑都是可能的。 -
file0
源文件的名稱(可選) -
line
一個數字 -
msg
此屬性尚不存在,但未來能夠爲每一個位置添加一條短消息。
格式化輸出
若是想從新格式化輸出,使它看起來不一樣,可使用模板。
要得到 Visual Studio 兼容的輸出,可使用 --template=vs
:
cppcheck --template=vs gui/test.cpp
- 1
輸出將以下所示:
Checking gui/test.cpp…
gui/test.cpp(31): error: Memory leak: b
gui/test.cpp(16): error: Mismatching allocation and deallocation: k
要得到 gcc 兼容的輸出,可使用 --template=gcc
:
cppcheck --template=gcc gui/test.cpp
- 1
輸出將以下所示:
Checking gui/test.cpp…
gui/test.cpp:31: error: Memory leak: b
gui/test.cpp:16: error: Mismatching allocation and deallocation: k
能夠編寫本身的模式(例如,逗號分隔格式):
cppcheck --template="{file},{line},{severity},{id},{message}" gui/test.cpp
- 1
輸出將以下所示:
Checking gui/test.cpp…
gui/test.cpp,31,error,memleak,Memory leak: b
gui/test.cpp,16,error,mismatchAllocDealloc,Mismatching allocation and deallocation: k
支持如下格式說明符:
-
callstack
調用棧 - 若是可用 -
file
文件名 -
id
消息 id -
line
行號 -
message
詳細的消息文本 -
severity
一個消息的類型/等級
支持轉義序列: \b(退格)、\n(換行)、\r(換頁)、\t(水平製表符)