Applistar

7. 1 C言語および C++言語共通のコーディングスタイル

TOP > 7 モデリングガイドライン > 7. 1 C言語および C++言語共通のコーディングスタイル
  7. 1 C言語および C++言語共通のコーディングスタイル  

7. 1. 1 はじめに

この章では、MISRA-Cより、SystemCのコーディングでも 有用なルールを採用しています。

MISRA-Cの基になっているC言語規約はC90と呼ばれる ISO/IEC 9899-1990 です。

コンパイラの中には、ANSI C準拠と謳っているものがありますが、これは、そのまま ISO C準拠と読み替えてかまいません。 これは、ISO Cの言語規格が、1989年に発表されたANSI Cの言語規約 (ANSI X3. 159:199) をもとにISO/IECで標準化を行い、1990年にISO/IECで標準化を行い、 1990年にISO/IEC 9899:1990として発表されたという経緯があるためです。

7. 1. 2 文字セット

Rule 5

ISO 9899で定義している文字や拡張表記のみ使用可能です。

Rule 6

文字型の値は、ISO 10646-1で定義・文書化されたサブセットに制限されます。

7. 1. 3 コメント

Rule 9(必要)

コメントは入れ子であってはならない。

/* こんな /* コメントは*/ 間違いのもと*/
Rule 10(推奨)

コード部は’コメントアウト’してはいけません。

ソースコードの一部をコンパイルしたくないという場合、#if指令など を用いるべきです。

7. 1. 4 識別子

Rule 11(必要)

(内部および外部)識別子は31文字を超えてはいけません。

Rule 12(推奨)

ある名前空間の識別子は別の名前空間の識別子と同じ名前(spell)で あってはいけません。

混乱のもとになります。

7. 1. 5 型

Rule 13(推奨)

char, int, short, long, float及びdoubleという基本型は使用 してはいけません。代わりに typedefで等価な型を宣言して利用してください。

intなどは、処理系依存で、16ビットで扱われたり、32ビットで 扱われたりします。

typedef unsinged logn int proj1_UI_32 /* proj1 用の符号無し32ビット型*/
Rule 14(必要)

char型は常にunsigned charかsigned charで定義して使用してください。

単なるchar型の宣言は処理系により符号付きで扱われたり、符号無しで 扱われたりする危険があります。

Rule 15(推奨)

浮動小数点の実装は、定義された浮動小数点規格に従いましょう。

ある浮動小数点規格に準拠したチップ、コンパイラなどの環境で動作が 保証されているプログラムを、他の環境へ移植した場合など、 同様な動作が保証されない場合があります。

Rule 16(必要)

隠蔽している浮動小数点のビット表現は、プログラマはいかなる方法でも 使用してはいけません。

浮動小数点のビット表現は、すべての処理系で同じであるという保証は ありません。このため、処理系によっては、プログラマが意図したとおりの 動作になりません。

Rule 17(必要)

typedef名は再使用してはいけません。 混乱の元です。

{
typedef unsigned char UI_8;
}
{
 unsigned char UI_8; /* NG typedefで宣言した名称と同じ名称の変数を定義 */
}
Rule 18(推奨)

定数は型を示す接尾語をつけて利用してください。

接尾語なしの定数の場合、intで表現できる範囲内であると、 無条件にintとして扱われてしまう危険があります。

Rule 19(必要)

8進数定数は利用してはいけません。

10進数として扱いたい場合、不用意に0をつけると8進数として 扱われてしまい、混乱のもとになります。

  UI_32 ui32_xy = 0123; /* NG 10進数の 123 にはならない */
Rule 20(必要)

すべてのオブジェクトと関数識別子は使用する前に宣言する必要があります。

Rule 21(必要)

内部有効範囲の識別子は、外部有効範囲の識別子と同じ 名前で使用してはいけません。

内部有効範囲の識別子が、外部有効範囲の識別子を隠してしまいます。 第3者はそれを意図してコーディングされたものか判断ができません。 そのため、プログラムの修正を行う場合など混乱を引き起こします。 その結果、保守性を低下させます。

Rule 22(推奨)

オブジェクト宣言の有効範囲はより広い有効範囲が必要でない限り 関数範囲としましょう。

有効範囲を限定することで、不用意な同一識別子の定義によるオブジェクト にたいする意図しない参照を回避できます。 「関数範囲」とは、関数の範囲を示す「ブロックスコープ」のことです。

Rule 23(推奨)

ファイルスコープのすべての宣言は可能な限りstaticにしましょう

ファイルスコープで行った宣言は、暗黙に外部結合になります。 static記憶域クラス指定子を用いることにより、オブジェクトが 外部結合になることを防ぎます。そのため、外部からの意図しない参照 や変更を防ぐことができます。

Rule 24(必要)

識別子は同一翻訳範囲において内部及び外部結合を同時にもっては いけません

同一翻訳範囲において、同じ識別子を複数箇所で宣言した場合の使い方です。 一方をstatic記憶域クラス識別子付き、もう一方をextern記憶域クラス 指定子つきで宣言することを禁止しています。 これは、staticと内部結合、externと外部結合の関係が変わることがあるからです。 場合によっては、未定義の動作となります。

Rule 25(必要)

外部結合の識別子は唯一の外部定義を持たなければなりません

外部定義の多重定義があってたとしても、処理系(コンパイラ)が 拡張仕様として実現しているものもあります。しかし、定義内容が 一致しないばあいや、2ヶ所以上で初期化がある場合の動作については 未定義です。 そのため、予測しない動作を引き起こす危険性があります。

Rule 26(必要)

オブジェクトや関数が2度以上宣言された場合、すべての宣言は 互換性を保たなければいけません。

外部結合で宣言された型が、外部結合で定義された型を異なっていても コンパイラは指摘しません。 また、コンパイラによっては動作が異なる可能性があります。

Rule 27(推奨)

外部オブジェクトは2つ以上のファイルで宣言すべきでありません。

複数ファイルにわたり同じ名前のextern宣言を使用すると

  • タイプミスを誘発する恐れがあります
  • 型の変更など行う場合、変更もれの恐れがあります

そのため、ヘッダーファイル1ヶ所で行うようにしましょう。

Rule 28(推奨)

register記憶域クラス指定子は使用すべきではありません

register記憶域クラス指定子を使用しても、実際レジスタに 割り当てられるか否かは条理系依存です。

Rule 29(必要)

タグの使用と宣言は一致しなければなりません。

構造体(struct)、共用体(union)または列挙型(enumeration type)の 宣言ではタグを与えることができます。 宣言でタグを与えた場合、それにつづいてタグを使用するばあい、宣言と 一環していなくてはいけません。

struct tag1 {
  UI_8 ui8_1;
  UI_8 ui8_2;
};

struct tag1 twoval ={0x0102};  /** NG 宣言と初期化の型が一致していない*/

7. 1. 6 初期化

Rule 30(必要)

すべての自動変数(ローカル変数)は使用する前に値を代入してください

明示的に初期化しない限り、ローカル変数の初期値は不定です。

Rule 31(必要)

配列や構造体をゼロ以外で初期化する場合、構造に対応した波括弧

{ }

を使用してください。

多次元配列を1対の'{}'でくくると各配列の先頭を間違うおそれがあります。 また、要素の数を間違える場合もあります。その結果、要素が予想外の値で 初期化されるミスを誘発します。

  7. 1 C言語および C++言語共通のコーディングスタイル  
TOP > 7 モデリングガイドライン > 7. 1 C言語および C++言語共通のコーディングスタイル