|
デバッグコードは、ほとんどの場合次のような形をしています。 |
|||
|
|
||||
|
そこで、これを1行で書けるようにすると楽です。それが ASSERT です。ASSERT を使うと次のように書けます。
もちろんこの場合もデバッグコードの一種なので、代入などの副作用のある式を書いてはいけません。ASSERT の条件式が評価される場合とされない場合で結果が同じにならなければなりません。 デバッグコードはリリース用にコンパイルするときには無視されるようにしなければならないので、ASSERT はマクロを使って例えば次のように定義します。 |
|||
|
|
||||
|
マクロ ASSERT は共通ヘッダファイル中で定義し、関数 DoAssert_() はグローバルに1度だけ定義します。DoAssert_() の中身もマクロ ASSERT の中に書いてしまえば良いと思われるかもしれませんが、それだとうまくいかない場合があります。たとえば単純に
と書くかわりに
としたい場合があります(こうするとプログラムが停止したときにファイル名と行番号が得られるからです)。しかし、DoAssert_() の中身をマクロ ASSERT の中に書いてしまっていると、「条件式の評価結果が一定です」というワーニングメッセージが出力されてしまうことがあります(優秀なコンパイラでワーニングレベルを最大にしている場合)。これは if 文が直接マクロ展開されて
となってしまうためです。 |
|||
|
実は、ANSI-C に assert() という命令があります。これは上で説明した ASSERT とほぼ同じです。assert() では、リリース用にコンパイルするときはマクロ NDEBUG を定義する決まりになっています。デバッグ時に定義するマクロ DEBUG とは使い方が逆なので注意が必要です。これまでに説明した
は
に相当します。 通常 assert() はそれぞれのプラットフォームに適した定義がされているはずなので、とりあえず次のようにしておけば ASSERT が使えるようになります。 |
|||
|
|
|
言うまでもないと思いますが、assert() をわざわざマクロ ASSERT でラッピングしているのは、後で ASSERT の動作を変えたくなった場合を想定してのことです。 なお、assert() を利用する場合は <assert.h> をインクルードする必要があります。詳しくは ANSI-C のリファレンスを参照してください。 |
|||
|
ASSERT は非常にに強力なツールです。まず、あなたが今までに書いたコードに ASSERT を埋め込んでみてください。パラメータのチェック、ポインタの NULL チェック、文字列の長さのチェック、その他いろいろな場面で利用価値があります。はじめのうちは、しょっちゅう ASSERT にひっかかって悩まされることになりますが、慣れてくると本当にバグが減ります。いつも「今満たされていなければならない条件は何か」と考えながら作ることによって、正確性が増します。それに開発期間もずっと短縮されます。 ただし1つだけ注意して下さい。それは、バグと実行時エラーの区別です。実行時エラーに ASSERT を適用してはいけません。 |
|||
(「プログラミングのはなし」は1998年1月から1999年1月にかけて作成されたコンテンツです。)