MISRA-C ガイドブック
最終更新日 2007年8月12日

MISRA-C ガイドブック の概要

組込み開発者におくるMISRA-C―組込みプログラミングの高信頼化ガイド』 はSESSAME Working Group 3 (MISRA-C 研究会)がまとめた車載用ソフトウェアのためのC言語プログラミング開発のガイドラインです。

※MISRA-C (Guidelines For The Use Of C Language In Vehiche Based Software)

1998年に発行されたMISRA-C Version1 に記載されている127のルールについて解説し、適用するために必要な考え方を提示しています。

また、車載用ソフトウェアに限らず、他分野の組込みソフトウェア技術者にとっても有益な内容を提供しています。

ISBN: 4542503348 日本規格協会 ¥3,570 (税込) MISRA-C研究会 (編さん)
お近くの書店で注文するか、インターネット書店等で購入できます。


主要目次

1. はじめに
2. 本書の位置づけ
3. MISRA-C適用における注意事項
3.1 ISO Cについて
3.2 メトリックスについて
3.3 サブセットの導入
3.4 ルールからの逸脱について
3.5 必要ルールと推奨ツールについて
3.6 ISO Cの附属書Gについて
3.7 副作用と副作用完了点について
3.8 ビットフィールドについて
4. 本書で使用している用語について
4.1 ブーリアン値を返す式、実質的なBool型、および論理値
4.2 forループ、for文、ループの本体、およびループカウンタ
4.3 関数型マクロ
5 ルール
5.1 環境
5.2 文字セット
5.3 コメント
5.4 識別子
5.5
5.6 定数
5.7 宣言と定義
5.8 初期化
5.9 演算子
5.10 変換
5.11
5.12 制御フロー
5.13 関数
5.14 前処理指令
5.15 ポインタと配列
5.16 構造体と共用体
5.17 標準ライブラリ
6. 参考文献
付録 A. ルール一覧
付録 B. ISO標準との相互参照表
付録 C. Koeningの章番号とページ番号との相互参照表
付録 D. MISRA-C と本書との引用対照表
付録 E. 附属書G(参考)可搬性

内容についての疑問点や不明点については sessame-misrac-query@blues.se.uec.ac.jp までご連絡ください


『組込み開発者におくるMISRA-C』 正誤表

        
該当個所 内容
1刷/ P.012
2.本書の位置付け5行目
製造工程だけにとどまらず
プログラミング工程だけにとどまらず

1刷/ P.26
4.2 forループ, for文, ループの本体, 及びループカウンタ[例]の図
※ forループを示す矢印を修正.

1刷/ P.120
5.11.6 ルール51(推奨) [例1]の補足の3行目
表現を持つかのように実行される.
表現を持つかのように実行される(C90 6.8.1).
※ 引用元を追記.

1刷/ P.131
5.12.7 ルール58(必要) 【潜在的問題】5行目
【サンプル】の[例3]のように
   
※ [例3]は存在しないため削除.

1刷/ P.126
ルール54(必要) [例3]の2行目
UI_16 ui16_var1, UI_16 ui16_var2, ui16_var3
UI_16 ui16_var1, UI_16 ui16_var2, ui16_var3;
末尾のセミコロン';'が不足していたため追記.

1刷/ P.120
ルール51(推奨) [例2]の2行目
#if ((END - START) - LEN) < 0)
#if (((END - START) - LEN) < 0)
左括弧'('が不足していたため追記.

1刷/ P.115
ルール48(推奨) [例1]の4行目
f64_var1 = ui16_var1 / ui_var2; /* NG: 演算結果=0.0 */
f64_var1 = ui16_var1 / ui16_var2; /* NG: 演算結果=0.0 */
変数名の誤りを修正.

1刷/ P.88
ルール34(必要) [例5]の2行目
extern func( UI_16 ui16_arg );
extern Bool func(UI_16 ui16_arg);
関数の戻り型が省略されていたため追記.

1刷/ P.154
ルール71(必要) [例3]の9行目
SI_16 si32_var;
SI_16 si16_var;
変数名の誤りを修正.

1刷/ P.158
ルール74(必要) [例1]の2〜4行目
extern SI_32 func( SI_32 si32_prm, SI_32 si32_prm,
UI_16 ui16_prm )

SI_32 func1( SI_32 si32_arg, SI_32 si32_arg, UI_16 ui16_arg )
extern SI_32 func( SI_32 si32_prm1, SI_32 si32_prm2, UI_16 ui16_prm )

SI_32 func1( SI_32 si32_arg1, SI_32 si32_arg2, UI_16 ui16_arg )
変数名の誤りを修正.

1刷/ P.163
ルール76(必要) [例2]の3行目
si32_var1 = func2(si32_var);
si32_var1 = func2();
実引数が誤って指定されていた点を修正.

1刷/ P.167
ルール79(必要) [例2]の3行目
extern void *func( UI_16 );
extern void *func1( UI_16 );
関数名の誤りを修正.

1刷/ P.175
ルール85(推奨) [例]の11行目
ui16_var = 2U
ui16_var = 2U;
末尾のセミコロン';'が不足していたため追記.

1刷/ P.207
ルール105(必要) [例2]の15行目
else if( si16_var1 == MAC_FUNC2 )
else if( si16_arg1 == MAC_FUNC2 )
変数名の誤りを修正.

1刷/ P.211
ルール106(必要) [例4]の2行目
extern void func1( SI_16 );
extern void func1( SI_16 * );
引数型の誤りを修正.

1刷/ P.230
ルール115(必要) [例2]の3行目
void * memcpy_word( void *v_prt1, const void *vc_ptr2, size_t size )
void *memcpy_word( void *v_ptr1, const void *vc_ptr2, size_t size )
変数名の誤りを修正.

1刷/ P.26
4.3 関数型マクロ 16行目
(3) (1)と(2)以外に置き換えるマクロ
(3) (1)と(2)以外のマクロ
表現の変更

1刷/ P.54
ルール14(必要) [例]の6〜7行目
SI_8 si8_var = -1; /* 補足1参照 */
char c_var = -1; /* 補足2参照 */
SI_8 si8_var = -1; /* OK:補足1参照 */
char c_var = -1; /* NG:補足2参照 */
コメントにOK、NGを追加

1刷/ P.79
ルール31(必要) 【解説】の下から3行目
MISRA-Cルール31の注では、「先頭要素は、ゼロ又はNULLに初期化されるべきである」としており、
MISRA-Cルール31の注では、「配列または構造体は、その先頭要素のみを明示的に初期化指定することで全ての要素をゼロまたはNULL に初期化ができる。もしこの方法を採用するのならば、先頭要素は、ゼロまたはNULL に初期化されるべきであり、入れ子の大カッコは不要である。」としており、
引用を正確な文章に修正

1刷/ P.98,99
ルール38(必要) [例5]サンプルコード

[file1.c]
UI_16 ui16_var1, ui16_var2, ui16_var3;
UI_16 *pui16_var = &ui16_var3;

void func1( void )
{
ui16_var1 = 16;
ui16_var2 = 24;
*pui16_var = 55;
}

void func2( void )
{
*pui16_var = 11;
}


[file2.c]
UI_16 ui16_var4, ui16_var5, ui16_var6;
extern UI_16 ui16_var1, ui16_var2;
extern void func1( void );
extern void func2( void );
extern UI_16 *pui16_var;

void func3( void )
{
func1();
ui16_var4 = ui16_var1 >> ui16_var2; /* NG: 補足1参照 */
ui16_var5 = ui16_var1 >> *pui16_var; /* NG: 補足2参照 */
func2();
ui16_var6 = ui16_var1 >> *pui16_var; /* OK: 補足3参照 */
}

補足 1: >>演算子の右オペランドui16_var2の値は, 汎整数拡張前のui16_var1の ビット幅以上である. この場合は, コンパイラ,静的チェックツールで のチェックはできない.

補足 2および補足 3: 補足 2 の >> 演算子の右オペランド *pui16_var の値は,汎 整数拡張前の ui16_var1 のビット幅以上であるので NG である. 補足 3 の演算子の右オペランド *pui16_var の値は, 汎整数拡張前の ui16_var1 のビット幅未満なので OK である. このようにシフト式の右オペランドにポインタ変数を使用している場合 は、より注意が必要で、ポインタ変数の指す先まで確認する必要がある. このような場合は、動的にシフト演算子の右オペランドをチェックした 方がより安全である.
全て変更

1刷/ P.133
ルール59(必要) [例1]の6行目
ui16_var2++; /* OK: 実効行が1行であっても波括弧でくくられている */
ui16_var2++; /* OK: 実行文が1行であっても波括弧でくくられている */
誤記修正

1刷/ P.135
ルール60(推奨) 【備考】の3行目
また、else節にコメントのみを記述する場合は、ルール54の解説に従うべきである。
また、else節に空文のみを記述する場合は、ルール54の解説に従うべきである。
誤記修正

1刷/ P.144
ルール65(必要) [例2]の5行目
for(ui16_cnt = 0 ; ui16_cnt == 5U ; ui16_cnt++)
for(ui16_cnt = 0 ; ui16_cnt <= 5U ; ui16_cnt++)
終了条件の誤りを修正

1刷/ P.153
ルール71(必要) 【解説】の1行目
プロトタイプ宣言なしで関数の呼び出しを行うと、signed intの型を持つ関数と解釈される。
プロトタイプ宣言なしで関数の呼び出しを行うと、intの型を持つ関数と解釈される。
signed intをintに修正

1刷/ P.213
ルール107(必要) [例2]の8行目
if ( psi16_arg == 0 ) /* ヌルポインタの判定 */
if ( psi16_arg == NULL ) /* ヌルポインタの判定 */
0をNULLに変更

2刷/ P.207
ルール105(必要) [例2]の中央近辺
((void (*)(SI_8))vfp_arg2)(10); /* NG: 補足参照 */
((void (*)(SI_16))vfp_arg2)(10); /* NG: 補足参照 */
型の誤りを修正.

2刷/ P.228
ルール114(必要) 上から6行目
[例4] OK:実際の・・・
[例4] NG:実際の・・・
誤記を修正.

6刷/ P.94
ルール37(必要) [例2]の補足の1行目
補足: si16_var3が符号付き
補足: si16_varが符号付き
変数名の誤りを修正.

6刷/ P.111
ルール46(必要) [例1]の補足2の1行目
ui_16_cnt++
ui16_cnt++
変数名の誤りを修正.

6刷/ P.63
ルール20(必要) [例3]の1〜2行目
F_32 f32_var1 = 0.0F;

f32_var1 = func2(); /* NG: 補足参照 */
F_32 f32_var = 0.0F;

f32_var = func2(); /* NG: 補足参照 */
変数名の命名規則を他の例と統一.

6刷/ P.77
ルール30(必要) [例1]の2行目
extern SI_16 func2( void )
extern SI_16 func2( void );
末尾のセミコロン';'が不足していたため追記.

6刷/ P.263
表E-3 G.3処理系定義の動作41
翻訳日付及び翻訳時刻がそれぞれ有効でない場合における__DATA__及び__TIME__の定義(6.8.8)。
翻訳日付及び翻訳時刻がそれぞれ有効でない場合における__DATE__及び__TIME__の定義(6.8.8)。
__DATE__が__DATA__となっていたため修正.

6刷/ P.164
ルール77(必要) 【解説】P.164の7行目
・long = unsigned long = long int = signed long int
・long = signed long = long int = signed long int
unsigned long を signed long に修正