コーディング規約の勘所

no extension

今回はちょっと趣向を変えて「コーディング規約」について考察していきたいと思います。 なので, エンジニア以外の方には退屈な内容かもしれません。 更に私は典型的な職業プログラマですので, これから書くことはオープンソース開発の現場などでは適用できない場合もあると思います。 あしからずご了承ください。

そもそも私は「原則としてコーディング規約は不要」だと思っています。 自由な発想が求められる開発などの現場でコーディング規約を適用することは足枷でしかありません。 ある程度以上のプログラミング経験をつんだ方は, それぞれ独自のコーディング・スタイルを持っています。 そのスタイルを外的要因で崩されることは(人によっては思考が停止するほどの)大変な苦痛なのです。 しかしそれでもコーディング規約は必要であるとされます。 何故でしょう。 それはソフトウェアの製造プロセスにおいて製品の品質を落とすコーディング・スタイルが存在するからです。 つまりコーディング規約というのは「開発」ではなく「製造」において必要な手段(あるいは道具)であるということです。 これは大事なポイントです。

では, これからもう少し詳しく述べていきましょう。

ソフトウェアにおける「開発」と「製造」は何が違うのでしょうか。 品質という観点で考えると, あるはっきりとした違いがあることが分かります。 それは, 製造によってアウトプットされたソフトウェアは顧客の要求を過不足なく満たしていることを保証している, ということです。 これには二つの意味があります。 ひとつは「顧客の要求」が製造可能なレベルまで具体化されていることで, もうひとつは具体化された「顧客の要求」からの逸脱(Deviation)がないことです。

「逸脱がない」ことは「バグがない」こととは違います。 ソフトウェアの性質上「バグがない」プログラムを作ることは(それが大規模であればあるほど)至難の業です。 しかし「逸脱がない」プログラムを作ることは「バグがない」プログラムを作るよりもはるかに楽です。 何故なら「逸脱がない」プログラムを目指すことでエンジニアの責任範囲が有限になるからです。 顧客は「要求」に対して責任を持ち, 作り手であるエンジニアたちは要求に対して「逸脱がない」ことで自らの責任を果たします。 責任を分担しているわけです。

エンジニアは自らの責任を果たすために製造に「プロセス」という概念を持ち込みました。 製造をいくつかの「工程」に分解し, 工程と工程の継ぎ目(マイルストーン)ごとにチェックポイントを設けて逸脱をなくそうとします。 製造においては「プロセス」は常に改良されます。 よく「ソフトウェアは永遠にベータ版」などと言われますが, 製造の現場においては「プロセス」こそが「永遠にベータ版」なのです。 コーディング規約もそうした「プロセス」に組み込まれるものです。

コーディング規約がプロセスに組み込まれるということは, 個々のプロジェクトに特化したコーディング規約ではダメだということです。 コーディング規約でよく見受けるのは, やたらとコーディングの書式やネーミング規則にこだわっているものです(まぁ私も昔そういう規約を作ったことがあるので他人のことは言えませんが)。 インデント幅はいくつとか C 言語ならブレス記号の位置とか関数名は最初が大文字で始まらなければならないとかいったものです。 しかしこれらの内容は使用する外部ライブラリやフレームワークあるいは参加するエンジニアの顔ぶれなどで容易に変わってしまうものです。 ソースコードの可読性と可搬性がごっちゃになっているケースともいえます。 あるソースコードが読みやすいかどうかは主観的なもので, 人によって感じ方は異なります。 こういう内容はプロジェクトのメンバ間で合意をとりつけるかコーディング例を示したテンプレートファイルを用意しておけば済む話です。 プロジェクトが終了してソースコード管理が他の人たちの手に渡れば読みやすさは変わってしまいますし, たとえ同じ人でも時間がたてば感じ方も変わります。 (私も数年前に自分が書いたコードを見て思わず「誰や! こんな変なコーディングしてる奴」とかツッコんでしまうことはあります)

ではどんな内容ならいいのでしょう。 C 言語で組み込み用途ならよいお手本があります。

組込み開発者におくるMISRA-C
MISRA-C研究会編
日本規格協会 (2004.5)
通常1-3週間以内に発送します。

MISRA-C とは欧州の自動車業界団体 MISRA (Motor Industry Software Reliability Association)が作成した車載用ソフトウェアを対象としたプログラミングガイドで, 欧州のみならず北米や日本でも事実上の標準となっています。 MISRA-C では127個のルールを定めていますが, これらを更に「必要(Required)」と「推奨(Advisory)」の二つに分類しています。 必要ルールはエンジニアに強制的に課せられるルールで, このルールから逸脱しなければならない場合は手続きを踏んで文書化と承認を行わなければなりません。 推奨ルールはそこまで厳しくなく逸脱時の手続きも必要ありません。 しかしだからといって無視してよいわけではありません。 各ルールにはルールの詳細(何故そのルールが必要か)と逸脱の判断基準とサンプルコードが載っています。 これらを参照して本当に逸脱しても大丈夫なのか判断する必要があります。

これをルール作成者の視点で見ると, ルールの必要性を合理的に説明できなかったり頻繁に逸脱が発生する状況はマズいです。 前半で述べたようにソフトウェアで重要なことは「逸脱がない」ことです。 遵守できない, あるいは誰も遵守してくれないルールがあるということは, それを定めたコーディング規約やコーディング規約を利用するプロセス自体に何かしら問題があるということです。 問題は速やかに改善されなければなりません。 プロセスは永遠にベータ版なのです。

またルールをその必要性も含めて正しく理解するということはスキルの向上(つまり教育)にも役立ちます。 ソフトウェアはエンジニア間のスキルのばらつきが品質にダイレクトに反映されてしまいます。 ある天才ハッカーがひとりで何もかも取仕切るというのなら別ですが, 通常の製造現場でそのようなことはまずありません(っていうか,そもそも製造の現場にハッカーがいるというのは人的リソースの無駄遣いですが)。 現場には様々な人がいてそれぞれスキルは異なっているのが普通です。 そのばらつきを品質に影響しない程度にまで揃えるのは意味があります。 コーディング規約を作成するならそこまで考えるべきです。

上で紹介した MISRA-C の本では, いかにしてコーディング規約をプロセスに組み込んでいくかについて詳しく解説しています。 例えば MISRA-C の127というルール数は充分多いと思いますが, 実際にはローカルルールを合わせると数百個くらいになるようです。 もちろんこれだけの数のルールを人力でチェックするのは無理です。 最近は MISRA-C に対応した構文チェッカも増えてきたので随分楽になりました。 そういったツールを使っていくこともプロセスとして組み込んでいく必要があります。

もちろんコーディング規約だけでは拾えない内容もあります。 例えば, あるロジックがスレッドセーフか否かといった内容はコーディング規約に盛り込むべきではありません。 おそらくそういった内容は別のレイヤでチェックすることになるでしょう。 コーディング規約はプロセスのある一部しかカバーしません。

いかがでしたでしょうか。 この記事が何かのお役に立てれば幸いです。