DOSEIの日記

技術メモ+日常ログ

assertion プログラミングのすすめ

assertion とは id:DOSEI:20041116:p1 に書いたとおり。

次の定理が成り立つ。

プログラムにバグがない ⇒ 全てのアサーションは真

逆は成り立たないが、十分多くのテストがアサーションを真にするならば、プログラムにバグがある可能性を下げることができる。したがって、プログラムを改変していく過程で、常にアサーションを成り立たせるように努力すればよい。また、変更をするたびに、テストを増やすとよりよい。

アサーションを使う上で注意すること。

  • assertion は実行時エラーを見つけるためのものではない。 assertion は、「仕様」をコード化する手法であり、「想定されるエラー状況」とは区別される。たとえば、「ファイルを開くことに失敗した」のがその関数で想定される状況であるなら、「バグ」ではないのだから、「ファイルは必ず開く」という assertion はできない。
  • assertion は一度書いたら、削除する必要はない。なぜなら、正しいプログラムに対してなんら制約を与えるものではないから。言語またはコンパイラの支援により、バイナリから完全に消し去ることもできる。

C 言語では

C 言語系で提供される assert() マクロ (in assert.h) は、 assertion が成り立たない場合に、その行と assertion 式を表示してアボートする。この場合、そのアサーションの意味合いがコメントで書かれていると理解できない。そこで、次のように書くことをお勧めする。*1

assert( (0 < x && x < w) && "x must be in image area");

文字列リテラルは非 0 なので、常に真である。このマクロは、 NDEBUG (たぶん、「デバッグ中ではないよ!」フラグ)が定義されているとき、ソースから消えるようになっている。 gcc では、 -D NDEBUG オプションをつければよろしい。

*1:'C++ Coding Standards', ハーブサッター他, 68項, pp. 130--131