今更だけど、Cppcheckを使って初音ミク冒険記のソースを静的テストしてみた
Astlibraの作者のKEIZOさんが
BBSでメモリアクセスエラーに関する書き込みをしていたので
いまどきだとオープンソースでメモリアクセスエラーとか検出するような
ツールって無いんだろうかと思い、調べてみました。
有償のVisual Studioだとできたと思うんだけど
無償のExpressではできないと思っていた静的テストが
無料でできるツールCppcheckを見つけたので、今更だけど
初音ミク冒険記のソースで実行してみた。
※注1
「無料のVisual Studio 2012 ExpressでC++の静的コード解析ができるよ。」
という記事によると、Visual Studio 2012だとExpressでも静的テストができるようになったらしいです。
※注2
「VC2012 Expressで静的コード分析」の
最後の方によるとVC++2010でもSDKと連動させると使うことができたらしいです。
参考にしたのは
「大人になったら肺呼吸」の記事
「Visual Studio + CppcheckでC++コードの静的解析ができる」です。
以下の環境で動作させてみました。
・Windows 7
・Visual Studio 2008 Express Edition SP1
・Cppcheck 1.63.1
CppCheckはコチラからダウンロードしました。
その後、Visual Studioのメニュー「ツール-「外部ツール」を設定します。
外部ツールの画面が出たら「追加」ボタンをクリック。
最初は、上記のサイトの通りに
タイトル:Cppcheck
コマンド:cppcheck.exe
引数:--enable=all --template vs $(ItemPath)
と設定したんですが
これだとソース単位でのチェックになってしまい
初音ミク冒険記みたいにソースの数が多いとツライことが分かりました。
--enable=allは全部のチェックをを有効にする、
--template vsというのはVisual Studioスタイルで出力するって意味で
$(ItemPath)は、現在開いているソースって意味らしいです。
「cppcheck 日本語マニュアル」
そこで、ちょっと設定をいじって以下のようにしてみました。
タイトル:Cppcheck本体
コマンド:cppcheck.exe
引数:--enable=all --suppress=syntaxError --template vs $(SolutionDir)
対象ソースを$(SolutionDir)ということでソリューションファイル(.sln)のフォルダとし
さらに--suppress=syntaxError(文法エラーをはじく)をつけます。
なんで文法エラーを弾くかというと
Visual Studioでコンパイルできたら文法エラーは無いはずというのと
もっと早くに調べたらVC++のコーディングが楽になったのに・・・に書いた
#pragma region リージョン名
#pragma endregion
を使っていたため、リージョン名に日本語を使うと
error: The code contains characters that are unhandled. Neither unicode nor extended ASCII are supported. (line=30, character code=83)
みたいに、しこたま怒られるためです。
(まぁ、もともと海外のソフトだしね)
実際、日本語の関数名や変数名を使っているAstlibraのソースで試した所
このエラーが大量に出ていて、何が本当の警告なのか分からないくらいでした。
で、この設定にして動かしてみたところ
Astlibraは、警告メッセージも少なく良い感じなのに
うちのは、いっぱい出てくるねぇ・・・
Cppcheckでは主に以下のチェックを実施してくれます。
・範囲外例外のチェック
・クラス毎のコードチェック
・例外のチェック
・メモリリークのチェック
・推奨されない関数の警告
・不正な使い方のSTLに対するチェック
・初期化されていない変数、未使用変数のチェック
初音ミク冒険記で多いものを列挙すると
■style: The scope of the variable 'idx' can be reduced.
(変数idxのスコープは、局所化できます)
<言い訳>
本当はループ変数のidxとかは
for(int idx = 0; idx < MAX_YYYY; idx++){
みたいに書けるんですが、PSP版の頃は、この書き方をすると
コンパイルが通らなかったので、あえてやってません。
まぁ、ブロックを示す{~}の間でしか使わないものは
そっちに宣言しても良いんですがね。
■style: Variable 'idx' is assigned a value that is never used.
(変数idxに設定した値は、使われていません)
<言い訳>
C言語だと変数の初期化漏れが怖いので、とりあえず変数宣言と同時に0で初期化して
実際に使うとき直前で正式な初期化を行ってます。
他には戻り値の受け捨て(戻り値チェックをやることになった時に備えて)や
DrawFormatString( posX, posY, SKYBLUE, "防御属性"); posY = posY + 20;
と言った行を連続して書いて
後から行が増えた時にもコピペして使えるようにしたりといったことを
意識的にやっていたりします。
■performance: Variable 'posX' is reassigned a value before the old one has been used.
(変数posXは、前に設定した値を使っていません)
<言い訳>
前述のようにとりあえず0を設定していたりするので
正式に使う段階で、前に設定した値を使っていないってことがあります。
■使ってよかったなと思うこと
iいくつか無駄な条件分岐や未使用の関数が見つかったこと
それと書式文字列の微妙に誤った使い方をしていた箇所をみつけられたこと
さらに「ソースコードの静的解析ツール CppCheck と Jenkinsプラグイン」によると
CppcheckはJenkinsとも連動できるらしい。
Jenkinsは、Traclightningをインストールすると一緒にインストールされるので
連動することができるかもしれないなぁ。
実は、最近、仕事でやっかいな障害対応をしていたこともあって
こういう無償で使える品質強化ツールは、とてもありがたいと思うんですよ、これが。
| 【固定リンク】 | 【コメント (2)】 | 【トラックバック (0)】