Cppcheckの使い方の詳細と設定

   2017/04/30

前回、Cppcheckの簡単な使い方を紹介しました。 ここでは、もう少し掘り下げて使い方の詳細と設定方法について紹介していきます。 Cppcheckをまだ使ったことが無い方は、こちらから先に。 既にインストールや簡単な使い方を試したことがある方に詳細を説明していきます。 動作環境は、同様に以下の環境です。

  • CentOS6.8 x86_64

使い方の詳細

ディレクトリ内の全てのファイルを検査

通常、プログラムはプロジェクトディレクトリ内にある多くのソースファイルから成り立っています。 そのディレクトリ内にある全てのソースファイルをチェックする方法から。

$ cppcheck /path/to/your_dir

 

サンプルのコードですと面白くないので、C/C++で書かれたオープンソースをダウンロードしてCppcheckを実行してみました。 サンプルとして選んだソースは、MariaDBのコネクターです。私は、データベースを扱うことが多く、たまたまMariaDBのソースが手元にあったからです。(mariadb-connector-c-2.3.2-src.tar.gz)

 

$ cppcheck mariadb-connector-c-2.3.2-src
Checking mariadb-connector-c-2.3.2-src/examples/mysql_affected_rows.c…
1/109 files checked 0% done
Checking mariadb-connector-c-2.3.2-src/examples/mysql_debug.c…
2/109 files checked 0% done
Checking mariadb-connector-c-2.3.2-src/examples/test_output.c…
[mariadb-connector-c-2.3.2-src/examples/test_output.c:67]: (error) Resource leak: fp_out
[mariadb-connector-c-2.3.2-src/examples/test_output.c:67]: (error) Resource leak: fp_exp
Checking mariadb-connector-c-2.3.2-src/examples/test_output.c: _WIN32…
...
...

 

実行開始して直ぐに、「Resource leak」のエラーが出てきましたが、本当にそこにバグがあるかどうかは、もちろんよく調べなければ分かりません。 cppcheckが誤検出しているかもしれないからです。

あるディレクトリやファイルを検査対象から外す

ディレクトリやファイルを検査対象から外すには、-i オプションを追加します。

$ cppcheck /path/to/your_dir -i/path/to/your_dir/hoge

 

これでhogeの配下は検査されなくなります。

重要度

error バグが見つかった際に使われる。
warnning バグ回避するためのお勧め。
style 綺麗なコードになるように使われていない関数などを表示。
performance コードの実行速度が速くなるようなお勧め手法。
portability 64-bit ポータビリティ。 また別のコンパイラへのポータビリティ。
information 設定に関する問題。

これらの重要度の中でerrorだけがデフォルトで表示されます。 ––enable オプションを使うことによってその他についても表示することが可能となります。

$ cppcheck ––enable=warning /path/to/your_dir

 

全ての重要度を表示するには、––enable=all を付けて実行します。 また例えば、warningとperformanceだけを対象に検査したい場合は、カンマ区切りで ––enable=warning,peformance のように指定します。

Inconclusive check

Cppcheckは、初期設定で確実だと思われるエラーメッセージのみを表示します。 もしこの挙動を変更し、不確かな部分についてもメッセージを出したい場合は、––inconclusive を付けて実行します。

$ cppcheck ––inconclusive /path/to/your_dir

 

CMakeとVisual Studio

CMakeまたは、Visual Studioを使っている場合は、––project を付けて実行すると良いようです。 例えば、

$ cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON

 

とすると、cmakeは、コンパイル時のオプションが列挙されたJSONファイルを作成します。 ファイル名は、compile_command.jsonとなりますので、そのファイルを指定して実行します。

$ cppcheck ––project=complile_commands.json

 

Visual Studioを使っている場合は、

$ cppcheck ––project=hoge.sln
$ cppcheck ––project=hoge.vcxproj

 

のように実行します。

プリプロセッサ

Cppcheckは、ソースコードがプリプロセッサで条件分岐されて何パターンかのコンパイルができるような場合、全パターンについて検査を実行します。 この挙動を変えるには、定数をdefineした状態で実行すると良いようです。

$ cppcheck -DHOGE /path/to/your_dir

 

逆にある定数がdefineされていない状態にして実行することもできます。

$ cppcheck -UHOGE /path/to/your_dir

 

メモリリーク

malloc等で割りあてられたメモリポインタは、他の関数に渡されていったりすると、その先で解放されるかどうか把握するのが大変です。 Cppcheckも自動で判断することはできないので、ポインタを渡された関数側で解放することをデフォルトで想定しています。 この挙動を変更したい場合は、設定ファイル(XML)を作成し、Cppcheck実行時にそのファイルを指定してあげる必要があります。 例えば、次のコードをtest.cppとして保存します。

 

str_func関数が、受け取ったポインタでメモリを解放しないのでしたら、次のようにXMLで設定ファイルを準備します。 (例えばファイル名をmemcheck.cfgとして)

 

この設定ファイル(memcheck.cfg)をcppcheckに渡して実行します。

$ cppcheck ––library=memcheck.cfg test.cpp
Checking test.cpp…
[test.cpp:6]: (error) Memory leak: str

 

逆にもし、str_func関数がメモリを解放するのでしたら、次のようなXMLを準備します。 (ファイル名は同様にmemcheck.cfg)

 

$ cppcheck ––library=memcheck.cfg test.cpp
Checking test.cpp…

 

自分のプロジェクトに合わせて設定ファイルを作るのは少し大変かもしれませんが、一つのツールとして使って見るのはいかがでしょうか? 設定は上記以外にも、いろいろできるようですので、詳細はmanページなどを参考にして試してみて下さい。

  • このエントリーをはてなブックマークに追加
  • Pocket

この記事へのコメントはこちら