assert はいつ使えばいいの?

assert の説明では、「assert は通常のエラーチェックに使うものではないことに注意しましょう」と書きました。

では、いつ assert を使えばよいでしょうか?

ここでは assert を使うべきではない場合と、使ったほうがよい場合について書いてみたいと思います。

assert を使うべきではない場合

例えば、ファイルを開こうとしてファイルが開いたかどうかチェックする場合、例えばポインタ fp が NULL かどうかチェックするために assert( fp ) とやるべきではない、ということです。

このような場合は、条件判断として if( !fp ) { // エラー処理 ... とすべきです。

単にエラーの状況に対応しているだけです。

assert で 「開発者の意図」を記述する

では、いつ、何の目的で assert を使えばよいでしょうか

それを話すために少し私の経験を話します。私はマイクロソフトで働いていた頃は Windows、特に IIS のデバッグをしていました。

当然ながら Windows や IIS というのは大人数で開発されているので、他人のコードを読む必要があるわけです。 しかも、かなりの量のコードを的確に読む必要があります。

Windows のコードは大量の診断機能が実装されています。 標準ライブラリの assert をそのままの形では使わないにしても、assert 同等の診断マクロ等はほぼ完全に実装されています。

デバッグする側としても、アサートが埋め込まれているとコードを読むことは非常に分かりやすくなります。

それはなぜか。

assert という単語はもともと「主張する」という意味です。assert によって、開発者が「オレはこの部分を書くときに、 こういう条件を想定しているぞ」ということをはっきり示すことが出来るのです。

例えば、次のコードがあったとします。

void bar(int i, int j) {
  assert(i < 0);
  assert(0 < j);
  //...

すると、「私は bar 関数には i は 0 よりも小さく、かつ j は 0 より大きいという状況しか想定していない」 ということを明確にソースコードに記載しておくことができるのです。

このように書いておけば、他の人がこのコードを見たときに、もともと何を思ってコードを書いたのか良く分かるわけです。

このため通常、デバッグ用のビルド (checked build) でアサートを有効にしておき診断を容易にし、 プロダクション用のビルド (free build) でアサートを無効にしてパフォーマンスに影響しないようにする、という風にします。