メインコンテンツ

MISRA C Rule 8.x に対する違反の回避

MISRA C™:2012 および 2023 の Rule 8.1 ~ 8.14 により、宣言と定義に関する適切なコーディング手法が行われるようになります。この手法に従うことで、競合する宣言や意図しない変数の変更が発生する可能性が低くなります。

"コーディング中に" この手法に従わない場合、後になって、コードを MISRA C に準拠させるために大きな変更が必要になる可能性があります。大量の MISRA C 違反が生じる可能性があります。場合によっては、違反の修正中に別のルール違反を犯す可能性があります。そうではなく、コーディング中は次のルールに留意してください。見逃している可能性のある問題を見つけるには、MISRA C:2012 チェッカーまたは MISRA C:2023 チェッカーを使用します。

  • 宣言ですべてのデータ型を明示的に指定する。

    以下の k の宣言のような暗黙的なデータ型は避けます。

    extern void foo (char c, const k);

    代わりに、次を使用します。

    extern void foo (char c, const int k);

    こうすることで、MISRA C:2012 Rule 8.1 または MISRA C:2023 Rule 8.1 に対する違反を回避できます。

  • 関数の宣言時に、すべてのパラメーターの名前とデータ型を指定する。

    以下の宣言のようなパラメーター名のない宣言は避けます。

    extern int func(int);
    extern int func2();

    代わりに、次を使用します。

    extern int func(int arg);
    extern int func2(void);

    こうすることで、MISRA C:2012 Rule 8.2 または MISRA C:2023 Rule 8.2 に対する違反を回避できます。

  • 複数のファイルでオブジェクトまたは関数を使用する場合は、1 つのヘッダー ファイルのみでオブジェクトまたは関数を 1 回宣言する。

    複数のソース ファイルでオブジェクトを使用するには、そのオブジェクトをヘッダー ファイルで extern として宣言します。そのオブジェクトを必要とするすべてのソース ファイルにそのヘッダー ファイルをインクルードします。いずれかのソース ファイルでそのオブジェクトを定義します。次に例を示します。

    /* header.h */
    extern int var;
    /* file1.c */
    #include "header.h"
    /* Some usage of var */
    /* file2.c */
    #include "header.h"
    int var=1;

    複数のソース ファイルで関数を使用するには、その関数をヘッダー ファイルで宣言します。その関数を必要とするすべてのソース ファイルにそのヘッダー ファイルをインクルードします。いずれかのソース ファイルでその関数を定義します。

    こうすることで、次のルールへの違反を回避できます。

  • 1 ファイルでのみオブジェクトまたは関数を使用する場合は、指定子 static を使用してそのオブジェクトまたは関数を宣言および定義する。

    すべての宣言および定義で指定子 static を使用していることを確認します。たとえば、次の関数 func は、現在のファイルでのみ使用されることを意味しています。

    static int func(void);  
    static int func(void){    
    }

    こうすることで、次のルールへの違反を回避できます。

  • 1 つの関数内でのみオブジェクトを使用する場合は、そのオブジェクトを関数本体内で宣言する。

    関数の外部でオブジェクトを宣言しないようにします。

    たとえば、varfunc 内のみで使用する場合は、func 本体の外部で宣言します。

    int var;
    void func(void) {
       var=1;
    }

    代わりに、次を使用します。

    void func(void) {
       int var; 
       var=1;
    }

    こうすることで、次のルールへの違反を回避できます。

  • 関数をインライン化する場合は、指定子 static を使用してその関数を宣言および定義する。

    関数定義に inline を追加するときは必ず static も追加します。

    static inline double func(int val);
    static inline double func(int val) { 
    }

    こうすることで、MISRA C:2012 Rule 8.10 または MISRA C:2023 Rule 8.10 に対する違反を回避できます。

  • 配列を宣言する場合は、サイズを明示的に指定する。

    以下のような暗黙的なサイズ指定は避けます。

    extern int32_t array[];

    代わりに、次を使用します。

    #define MAXSIZE 10 
    extern int32_t array[MAXSIZE];

    こうすることで、MISRA C:2012 Rule 8.11 または MISRA C:2023 Rule 8.11 に対する違反を回避できます。

  • 列挙を宣言する場合は、明示的な指定と暗黙的な指定が混在しないようにする。

    明示的な指定と暗黙的な指定の混在を避けます。最初の列挙定数は明示的に指定できますが、それ以降は、暗黙的な指定または明示的な指定を使用します。たとえば、以下のような混在は避けます。

    enum color {red = 2, blue, green = 3, yellow};

    代わりに、次を使用します。

    enum color {red = 2, blue, green, yellow};

    こうすることで、MISRA C:2012 Rule 8.12 または MISRA C:2023 Rule 8.12 に対する違反を回避できます。

  • ポインターを宣言する場合は、ポインターを使用してオブジェクトを変更する場合を除き、const 修飾子付きの型を参照する。

    参照されるオブジェクトを変更するためにポインターを使用する場合を除き、既定で const 修飾子付きの型を参照します。たとえば、次の例では、ptr は参照されるオブジェクトの変更に使用されません。

    char last_char(const char * const ptr){
    }

    こうすることで、MISRA C:2012 Rule 8.13 または MISRA C:2023 Rule 8.13 に対する違反を回避できます。