読者です 読者をやめる 読者になる 読者になる

ドキュメントの重要性

「コードを書くのは楽しいけど、そのドキュメントを書くのは面倒くさいよ。」
殆どのプログラマはそう思っており、私もそんなプログラマの一人だったりします。
しかしながら、ドキュメントのないプログラムというのは殆ど無意味であり、実用上の価値は皆無といえます。

整数配列の平均値を計算する関数を 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. (例外をスローする) を採用していたとして、そのことがドキュメントに明記されていなければ、ユーザが安心して利用できません。
何故なら、プラットフォームやバージョンが変わると、その挙動までもが変化する可能性があるからです。
なにより、そうした変更に伴う不具合が発生したとき、その責任が関数の製作者・利用者のどちらに かかるのか、ということが曖昧になってしまいます。

最近ではオープンソース化というのが進んでいるようですが、まともなドキュメントを伴わない無責任なコード開示がかなり見受けられます。 自分の作ったソフトウェアを多くのヒトに使ってもらいたければ、プログラムの性能・機能を充実だけでなく、きちんとしたドキュメントの用意も欠かさないようにしましょう。

担当: 成田