ソースコードは最も詳細な設計書である

そもそも設計書とは何か。私は設計書(specification)とは「要求仕様(requirements specification)の実現手順を記したものであり、実際に実現を行う者に対する要求」と理解している。関数実装に当てはめると、「ソースコードとは関数要求仕様の実現手順を記したものであり、実際に実現を行うコンパイラに対する要求」となる。そして開発用の、移行要求(機能追加や仕様変更など)を受け付ける可能性のある設計書は、設計の部品(コンポーネント)それぞれがどの要求を実現するために、どのような意図をもって実装されるのかということを把握できるようにするために、要求のトレーサビリティを持たなければならない。

class Foo
{
private:
    Foo(const Foo&);
    Foo& operator=(const Foo&);

C++プログラマC++コンパイラはこのクラス定義を見れば即座に「クラスFooはコピー不可である」と認識する。つまりコピーコンストラクタとコピー代入演算子を非公開メンバとするという定義文は「コピー不可」というクラス仕様を記述していることと相違ない。

然るに、このクラスがコピー不可と定義されていることについてこれで記述が十分かと言うとそんなことはない。これだけではクラスFooがなぜコピー不可なのかが判らない。つまり要求のトレーサビリティがない。そのため、たとえば移行要求によってこのクラスを「コピー可」に変更する必要性が生じたとき、その妥当性を的確に判断できない。コピー不可としている理由については、「コピー可にしなければならないという要求がない限り、クラスはコピー不可として定義する」という規則があってそれに則っているだけというのがもっとも有力だが、それを裏付ける情報はここにはない。

bool greater_than_5(unsigned short n)
{
    return (n - 5) > 0;
}

上記のC++関数定義は、intを4バイトとして扱う処理系では「n1が5より大きいならばtrueを返却」し、intを2バイトとして扱う処理系では「n1が0以外ならばtrueを返却」する。そしてこの挙動が、この関数の仕様ということになる。

とはいえ、普通に考えれば、この関数定義は単に「intが4バイト以上という処理系依存」なのであり、関数に対する要求仕様は「n1が5より大きいならばtrueを返却する」と考えるのが正しいように思われる。この認識が正しいかは、この関数に対する要求仕様書を見れば確認できるだろう。しかし、なぜ

return n > 5;

このように定義しないのかという理由は実装都合なので関数要求仕様書からは理解することはできない。可能性としては「特定の処理系では0以外との比較ができないという問題があり、それを回避しなければならない」「主要な処理系では5と比較するよりも0と比較した方がオブジェクトコードが最適化されることが確認されたため、人間にとっての解りやすさよりも計算機にとっての解りやすさを優先した」などのような、ソースコードの実現を担当するコンパイラの制限によるものから、「生産性のない関数でつまらないから少しでも小洒落た書き方をしてみようと思った」などといったコーダーの気まぐれまで考えられるが、確実に「これだ」と断言できる理由はない。この理由を即座にトレースできる状態になっていないとしたら、実装意図、すなわちこの実装を選択させた要求や制限が不明瞭ということで、これもまた一つの要求トレーサビリティが欠如した状態と言える。

ソースコードは最も詳細で正確な設計書である。ソースコードとそれを結合するための情報(言語規格、処理系、makefileなど)さえあれば、成果物となるソフトウェアの仕様まで書き上げることは可能である。しかしその「仕様」が正しいかどうか、すなわち本来の「要求」に適合しているか、またどのような「制限」があるかは正確には判らない。逆に言うと、要求や制限を正しく素早くトレースできるソースコードがあるならば、その言語を理解している人にとっては「完璧な設計書であり仕様書」と言うものになる。