「コードを書くのは楽しいけど、そのドキュメントを書くのは面倒くさいよ。」
殆どのプログラマはそう思っており、私もそんなプログラマの一人だったりします。
しかしながら、ドキュメントのないプログラムというのは殆ど無意味であり、実用上の価値は皆無といえます。
整数配列の平均値を計算する関数を C/C++ で書いたとすると、そのプロトタイプ宣言は次のようになるでしょう。
(引数 n で要素数を、lpan が配列領域のアドレスを指定します。)
//平均値の計算 double average(int n, const int* lpan); |
配列 { 10, 16, 17, 24 } (n = 4) を渡せば、戻り値 (double 型) の値は 16.75 となります。
実に単純明快。
このプロトタイプに基づいて、実装を行うものも至極容易に思えます。
//平均値の計算 double average(int n, const int* lpan){ int nSum =0; int i; for (i=0; i<n; ++i) nSum +=lpan[i]; return (double)nSum/n; } |
さて、実装を終えた時点でふと気が付きます。
この関数に空の配列を指定すると、最後の行でゼロ除算によるエラーが発生してしまうことに。
数学的には、空集合の平均は定義されません。
さて、この問題への対処法はいくつか考えられます
- 未定義 (処理系依存): 動作を保証しない。実行時エラーを起こすかもしれないし、でたらめな値を返すかもしれない。
- 不定: 戻り値の内容を保証しない。
- NaN (IEEE 754 規定) を返す
- 0.0 を返す
- 例外をスローする (C++ のみ)
ここでは、これらの対策のどれが良い・悪いといった議論はしません。
重要なのは、「どのような対策を採っているか」をドキュメントに明記するということです。
例えば、上記の e. (例外をスローする) を採用していたとして、そのことがドキュメントに明記されていなければ、ユーザが安心して利用できません。
何故なら、プラットフォームやバージョンが変わると、その挙動までもが変化する可能性があるからです。
なにより、そうした変更に伴う不具合が発生したとき、その責任が関数の製作者・利用者のどちらに
かかるのか、ということが曖昧になってしまいます。
最近ではオープンソース化というのが進んでいるようですが、まともなドキュメントを伴わない無責任なコード開示がかなり見受けられます。
自分の作ったソフトウェアを多くのヒトに使ってもらいたければ、プログラムの性能・機能を充実だけでなく、きちんとしたドキュメントの用意も欠かさないようにしましょう。