ソフトウェア関連の事業で、大規模で複雑なものは、色々なコーディングとガイドラインが必要になります。このガイドラインは、ソフトウェアを構築する時に入れなければならない基本法則から作られます。通常、以下のようなものになります。
a) どのようにコードを構築しますか?
b) どの言語を使いますか、もしくは使いませんか?
この法則を効果的にする為に、ルールは細く、簡単で忘れにくいものでなければいけません。
NASAで働く世界トップクラスのプログラマーは、コードを安全に構築できるようにガイドラインを作っています。事実、NASA’s Jet Propulsion Laboratory (JPL)などの多くの企業が、C言語でコードを作っています。 なぜなら、幅広いサポートがあるからです。評価モデル、デバッグ、コンパイル、ソースコード、メトリックスなどです。
これらのルールは、重要な箇所で必要になります。特に、生活に関するものは、正確で効果的でなくてはいけません。例えば、飛行機、宇宙船、原子力発電所などは、コンピュータで管理されています。
しかし、あなたは宇宙開発機関がどのように機械を動かしているか知っていますか? 上で話したNASAの 10のコーディングルールは、JPLのトップ科学者であるGerard J. Holzmannが作ったものを基本にしています。 これらは全てセキュリティパラメータ対策を主に考えられていて、他の言語でのプログラミングにも応用されています。
ルールNo. 1 – フローを単純にする
フローの構成をできるだけ簡単にしてください。goto文や再帰の中にsetjmp、longjmp を入れないでください。
理由: フローを単純にすると、コードを変更した箇所がわかりやすくなり、確認がしやすくなります。再帰がないと、graphというサイクリック関数が無くなります。このように、関連するコードは、関連づけされています。
ルールNo. 2 – 回転の上限を決める
回転数は上限に合わせてください。検証ツールで、上限数を超えて繰り返していないようになっている事を確認してください。確認できないと上限を超えて回転している可能性があります。
理由:上限を決めると、コードの異常を防ぎます。しかし、上限がないものに関しては当てはまりません。 (例えば、プロセススケジューラー) この時は、リバースエンジニアリングが適用されます。制限がない事を確認しなければいけません。
ルールNo. 3 – 動的メモリ確保を使わない
初期化した後に動的メモリ確保を使わないでください。
理由: mallocのようなメモリ確保やゴミ箱は、予想外の動きをすることがあります。さらに、メモリのエラーが発生することもあります。次のようなプログラムのミスが原因になります。
・容量以上のメモリを入れている
・free関数を忘れている
・解放したメモリを続けて使っている
・制限しなければいけないメモリを許可している
全てのモジュールの割り当てを固定すると、これらの問題が解決し、メモリの使用量を確認しやすくなります。
ヒープからクレームへのメモリ容量が足りない時は、スタックを使ってください。
ルール No. 4 – 関数を多く使わない
関数は、1行に1関数とした時、紙一枚に収まるようにしてください。コードは 60行を超えないようにしてください。
理由: 極端に長い関数は、あまりいい構造とは言えません。それぞれの関数は、確実に動くだけでなく、わかりやすくする必要があります。複数のディスプレイ上でどう表示されるか確認するのは難しいです。
ルール No. 5 – アサーション密度を低くする
プログラムのアサーションは、1つの関数につき2つまでにしてください。アサーションは、普段起こり得ないようなエラーがないか確認するためのものです。これらはBoolean式で定義されなければいけません。 アサーションがうまくいかない時は、リカバリーが起動するようにしておかなければなりません。
静的チェックで落ちたり固まったりする事がないと確認できれば、規則通りプログラムされています。
理由:企業のコーディングに関する統計によると、ユニットテストをすると、 10 から 100行のコードで少なくとも1つの欠陥を発見できます。アサーション密度を調整すると、欠陥を発見しやすくなります。
アサーションを使うと、コーディングの防御が強くなります。パラメータと戻り値とループ不変条件が正常に動いているか確認するのに使われます。アサーションは、クリティカルパスのテストを行った後、起動しないようにする事ができます。
ルール No. 6 – データの範囲を小さくする
これは、隠れたデータをデータをサポートするための基本です。全てのデータはできる限り小さくしなければいけません。
理由: データが絞られていないと、不具合が生じる原因になります。この法則を守っていないと、不具合が生じた時に原因を発見しにくくなります。
ルール No. 7 – パラメータと戻り値を確認する
ボイドを含まない戻り値は、それぞれの呼び出し関数で確認しなければいけません。パラメータが有効になっているかは、それぞれ関数の中で確認できます。
これは一番堅実なフォームで、この規則は、printfの戻り値にも当てはまります。そして、closeも確認しなければいけません。
理由: エラーが起きていない事を確認するには、戻り値が正確である必要があります。これは、 closeと printfでよくある事です。コーダーが、戻り値を無視するとプログラミングすると (偶然ではなく) 、戻り値が ボイドで処理されます。
ルールNo. 8 – プリプロセッサの使用を制限する
ヘッダーのファイルとマクロを定義する時は、プリプロセッサを制限してください。 再帰呼び出し、トークンとその他可変的なリストは許可してはいけません。
一般的なボイラープレートだけでなく、同じヘッダーが複数あるような広範囲にわたるものであっても、1つもしくは2つ以上の条件を入れてください。 コードが正常か、ツール単位でチェックできるようにしなければいけません。
理由: C プリプロセッサ は強力で広範囲に影響します。コードを複雑にし、テキストベースのチェッカーに不具合を生じさせます。プリプロセッサの影響は、形式的な言語定義にまでおよび、解読するのが難しくなります。
条件文の編集に気をつけるのも大切です。10の条件文には 1024種類 (2^10) のコードがあり、一つ一つテストする必要があります。
ルール No. 9 – ポインタの使用を制限する
ポインタの使用は限定的にしなければいけません。間接参照は1レベル以下にしてください。ポインタの間接参照は、typedefやマクロの中に入れてはいけません。 関数ポインタも許可してはいけません。
理由: ポインタは専門家でも間違いやすいです。プログラムの中のデータを確認しずらいです。特に、静的解析ツールでは難しいです。
関数ポインタも静的解析において注意しなければいけません。なので、どうしても使わなければならない時にだけ使うようにしてください。関数ポインタを使うと、再帰の欠陥がわかります。 そして、そこに欠陥を修復するためのツールを入れなければなりません。
ルール No. 10 – すべてのコードをまとめる
コードは、最初にまとめなければいけません。コンパイラの警告は、コンパイラがきちんとセットされている状態で使わなければいけません。 コードは、警告が出ない状態にしておかなければいけません。
最低でも1日に1回はすべてのコードを確認してください。 (できれば1回以上) 最高水準のコードは、アナライザーがコード化されていて、警告なしでコードを分析します。
理由: コード化するアナライザーはたくさんあります。無料のものもあります。これらを利用すれば、技術者にコードを作ってもらう必要がありません。もし、コンパイラや静的解析に異常が発見されたら、コードを自動で書き直します。なので、作業がより楽になります。