CppCheck介紹與使用

版權聲明:本文爲博主原創文章,未經博主容許不得轉載。 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(水平製表符)

相關文章
相關標籤/搜索