スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

テキストとしてのコーディング規約

愚者が賢者から学ぶことよりも、賢者が愚者から学ぶことのほうが多い。
モンテーニュ
今回の記事のテーマは「コーディング規約」です。コーディング規約とに含まれる、変数や関数の命名規則やら、コメントの書き方等の話題はここでも何度か取り上げましたが、今回は、コーディング規約の「テキスト」としての側面に焦点を当てたいと思います。

4798111899「コーディング規約」や「コーディングルール」というと、何だか型にはめられるという気がして、拒否反応を示す方もおられるでしょう。確かに「規約」とか「ルール」とかいう単語が入っているので、そのようなイメージは強いでしょう。しかし、中には「制約」というよりは「ガイドライン」と呼ぶべきものも多く含まれています。

ここで、コーディング規約導入の必要性について改めて整理してみます。細かく分類することも可能でしょうが、大きくは次の二つに大別できるかと思います。
  • スタイルを統一することで可読性を改善する。
  • 危険なコーディングを禁止し、品質を確保する。
前者は、複数人での作業を効率化するために存在します。変数や関数の命名規則やら、インデントの統一、一関数の最大行数の設定等があげられるでしょう。 それに対し後者は、移植性がない、可読性が悪い等の問題を排除するために、コーディング方法にルールを作るというものです。 オーバーラップする点も大いにあるとは思いますが、前者は「人間(他の担当者や保守担当者)のため」、後者は「プログラム自身のため」とも言えると思います。

さて、この後者の方ですが、内容的には規約というよりはガイドラインといった方が良いかもしれません。この点を積極的に利用すると、コーディング規約をプログラミングのテキスト・教科書としてとらえることができます。
以下の表に組込みソフトウェア開発力強化推進委員会による「コーディング作法ガイド」の一部を抜粋してあげさせて頂いています。それぞれの項目は、入門書でもよく言われるものから、意外と見落とされがちなもの、複数人の開発において重要となるルール的なもの、はたまた「実行時の利用スタックサイズが予測できないため再帰呼び出し関数は使用しない」といったような組込み特有のものまで、広範囲にわたってまとめられています。

構造体や共用体の比較にmemcmp を使用しない。

構造体や共用体のメモリには,未使用の領域が含まれる可能性があり,その領域に何が入っているか分からないので,memcmp は使用すべきでない。比較をするなら,メンバ同士で行う必要がある。また,構造体のメンバの詰め物,境界調整は処理系定義である。
<適合例>
struct {
  char c;
  long l;
} var1, var2;
void func() {
  if (s1.a == s2.a && s1.b == s2.b) {
/* …*/
<不適合例>
struct {
  char c;
  long l;
} var1, var2;
void func() {
  if (memcmp(var1, var2, sizeof(var1)) == 0) {
    /* … */
浮動小数点型変数は厳密な等式,非等式の比較はしない。【MISRA 13.3】

浮動小数点型は,見た目の値と実装された値は完全に一致していないので,比較は許容誤差を考慮して判定する必要がある。
<適合例>
#define LIMIT 1.0e-4
void func(double d1, double d2) {
  double diff = d1-d2;
  if (-LIMIT <= diff && diff <= LIMIT) {
    /* … */
<不適合例>
void func(double d1, double d2) {
  if (d1 == d2) {
    /* … */
下線で始まる名前(変数)は定義しない。

言語規格では,次の名前を予約済みとしている。
(1) 下線に続き英大文字1 字または下線に続き,もう1 つの下線で始まる全ての識別子は,いかなる使用に対しても常に予約済みである。
例: _Abc, __abc
(2) 1 つの下線で始まるすべての識別子は,通常の識別子及びタグ名前空間予約済みの名前を再定義した場合の動作は未定義である。
1 つの下線で始まり,小文字が続く名前は,ファイル有効範囲以外の部分では予約されていないが,覚えやすい規則とするため,下線で始まる名前すべてを使用しないという規則としている。
<不適合例>
int _Max1; /* 予約されている */
int __max2; /* 予約されている */
int _max3; /* 予約されている */
struct S {
  int _mem1; /* 予約されていないが使用しない */
};
実行時の利用スタックサイズが予測できな いため再帰呼び出し関数は使用しない。 【MISRA 16.2】  

内容は非常に充実しており、C言語プログラミングの初心者の方はもちろん、中級者以上の方にとっても、実践的な注意点が体系にまとめられており、非常に参考になると思います。例を見て頂けると分かるかと思いますが、危険なコーディングを禁止というよりは、「こんなことをするとこういうことになります。知ってますか?」というような失敗例・アンチパターンのカタログのようなものになっています。実際これらの多くは、言語仕様の勉強やサンプルコードだけではなかなか見えてこないもので、バグの定番のようなものが多いです。とはいえ、実際にバグを生めて苦い経験をしなくとも、事前にこのような失敗例を知っていることで、バグは回避できます。また、なぜそのようなコーディングがNGなのかを考えることで、言語仕様やプログラミングについての理解は深まります。

上の表のオリジナルはIPAのHPでPDFが無料配布(コーディング作法ガイド 0.8)されており、書籍化されたもの(組込みソフトウェア開発向けコーディング作法ガイド[C言語版])もあります。
無料で手に入るものですので、初心者以外の方も一度目を通してみられることをおすすめします。
(初出「組込みプレス Vol.3」を元に改稿)

【関連記事】
変数の命名規則
ビットシフトの落とし穴 - 算術シフトと論理シフト

【関連書籍】
組込みソフトウェア開発向けコーディング作法ガイド[C言語版] SEC
C++ Coding Standards―101のルール、ガイドライン、ベストプラクティス ハーブ・サッター他
リファクタリング―プログラムの体質改善テクニック
プログラミング作法
組込みプレス Vol.3
スポンサーサイト
人気エントリ
最近の記事
本のおすすめ

4274065979

4844337858

482228493X

4904807057

4873114799


最近のコメント
Links
プロフィール
  • Author:proger
  • 組み込み関係で仕事してます
ブログ内検索
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。