C言語ホーム > その他、C言語の詳細について > MISRA-C前ページ次ページ
サイト内検索:

MISRA-C

MISRA-CとはC言語のためのコーディング・ガイドラインです。MISRA-Cは、より安全なC言語サブセットとも言えます。MISRA-Cの遵守はシステムの安全性を高めます。



MISRA-C:2012 ルール一覧

<処理系>
分類項番カテゴリガイドライン
指針1.1必要プログラムの出力が依存する処理系定義の動作は、文書化され、理解されなければならない
<コンパイルとビルド>
分類項番カテゴリガイドライン
指針2.1必要すべてのソースファイルは、コンパイルエラーなしでコンパイルしなければならない
<要件のトレーサビリティ>
分類項番カテゴリガイドライン
指針3.1必要すべてのコードは文書化された要件へ追跡可能でなければならない
<コード設計>
分類項番カテゴリガイドライン
指針4.1必要実行時の障害は最小限に抑えられなければならない (補足)
指針4.2推奨アセンブリ言語のすべての使用は文書化されなければならない
指針4.3必要アセンブリ言語は、カプセル化され、隔離されなければならない
指針4.4推奨コードの一部を「コメントアウト」してはならない
指針4.5推奨可視性が重複して、同じ名前空間にある識別子は、表記上明白でなければならない (補足)
指針4.6推奨基本的な数値型の代わりに、サイズと符号の有無を示すtypedefを使用しなければならない
指針4.7必要関数がエラー情報を返す場合は、そのエラー情報を判定しなければならない
指針4.8推奨構造体や共用体へのポインタが翻訳単位内で逆参照されることがない場合、オブジェクトの実装は隠されなければならない
指針4.9推奨関数形式マクロの代わりに、互換性のある関数を使用しなければならない
指針4.10必要ヘッダファイルの内容が複数回インクルードされないように注意しなければならない
指針4.11必要ライブラリ関数に渡す値の妥当性を確認しなければならない
指針4.12必要動的なメモリ割り当てを使用してはならない
指針4.13推奨リソースに対する操作を提供するように設計された関数は、適切な順序で呼び出さなければならない (補足)
<標準C環境>
分類項番カテゴリガイドライン
ルール1.1必要プログラムは標準Cの構文と制約の違反が含まれていないものとし、処理系の翻訳限界を超えてはならない
ルール1.2推奨言語拡張を使用してはいけない (補足)
ルール1.3必要未定義の動作またはクリティカルな未規定の動作の発生があってはならない (補足)
<未使用コード>
分類項番カテゴリガイドライン
ルール2.1必要プロジェクトは到達不能なコードを含んではならない
ルール2.2必要デッドコードがあってはならない
ルール2.3推奨プロジェクトは未使用の型宣言を含んではならない
ルール2.4推奨プロジェクトは未使用のタグ宣言を含んではならない
ルール2.5推奨プロジェクトは未使用のマクロ宣言を含んではならない
ルール2.6推奨プロジェクトは未使用のラベル宣言を含んではならない
ルール2.7推奨関数内に未使用のパラメータがあってはならない
<コメント>
分類項番カテゴリガイドライン
ルール3.1必要「/*」や「//」という文字の並びをコメント内で使用してはならない
ルール3.2必要ラインスプライシングは//コメントで使用してはならない (補足)
<文字セットおよび字句規則>
分類項番カテゴリガイドライン
ルール4.1必要8進と16進の逆斜線表記は終了させなければならない
ルール4.2推奨3文字表記を使用してはならない
<識別子>
分類項番カテゴリガイドライン
ルール5.1必要外部識別子は異なったものにしなければならない
ルール5.2必要同じスコープと名前空間で宣言された識別子は異なったものにしなければならない
ルール5.3必要内側のスコープで宣言された識別子は、外側のスコープで宣言された識別子を隠してはならない
ルール5.4必要マクロ識別子は異なったものにしなければならない
ルール5.5必要識別子はマクロ名とは異なったものにしなければならない
ルール5.6必要typedef名は一意の識別子でなければならない
ルール5.7必要tag名は一意の識別子でなければならない
ルール5.8必要外部リンケージを持つオブジェクトや関数を定義する識別子は一意でなければならない
ルール5.9推奨内部リンケージを持つオブジェクトや関数を定義する識別子が一意でなければならない
<型>
分類項番カテゴリガイドライン
ルール6.1必要ビットフィールドは適切な型で宣言されなければならない (補足)
ルール6.2必要ビットフィールドで名付けられたシングルビットは符号付きの型であってはならない (補足)
<リテラルと定数>
分類項番カテゴリガイドライン
ルール7.1必要8進定数を使用してはならない
ルール7.2必要符号なしの型で表現されているすべての整数定数には「u」または「U」接尾語を適用しなければならない
ルール7.3必要小文字の "l"はリテラルの接尾語に使用してはならない
ルール7.4必要オブジェクトの型が「const修飾文字へのポインタ」でない限り、文字列リテラルをオブジェクトに代入してはならない
<宣言と定義>
分類項番カテゴリガイドライン
ルール8.1必要型は明示的に指定されなければならない
ルール8.2必要関数型は名前付きパラメータを持つプロトタイプの形式でなければならない
ルール8.3必要オブジェクトまたは関数のすべての宣言は、同じ名前と型修飾子を使用しなければならない
ルール8.4必要外部リンケージを持つオブジェクトや関数が定義される場合、その適合する宣言は可視でなければならない
ルール8.5必要外部オブジェクトまたは関数は1つだけの生存で一度だけ宣言されなければならない
ルール8.6必要外部リンケージを持つ識別子は、1つの外部定義を持たなければならない
ルール8.7推奨翻訳単位内での参照がただ1つである場合、関数やオブジェクトは外部リンケージを使用して定義してはいけない
ルール8.8必要静的記憶クラス指定子は、内部リンケージを持つオブジェクトおよび関数のすべての宣言で使用されなければならない
ルール8.9推奨識別子が単一の関数内にのみ出現する場合、そのオブジェクトはブロックスコープで定義されなければならない
ルール8.10必要インライン関数は、静的記憶域クラスを使用して宣言されなければならない (補足)
ルール8.11推奨外部リンケージを持つ配列を宣言する場合、その大きさは明示的に指定されなければならない
ルール8.12必要列挙子リスト内では、暗黙的に指定された列挙定数の値は一意でなければならない
ルール8.13推奨ポインタは可能な限りconst修飾型を指さなければならない
ルール8.14必要restrict型修飾子を使用してはならない (補足)
<初期化>
分類項番カテゴリガイドライン
ルール9.1義務自動記憶域期間を持つオブジェクトの値を値が設定される前に読んではいけない
ルール9.2必要集成体または共用体の初期化子は波括弧で囲まれなければならない
ルール9.3必要配列は部分的に初期化してはならない
ルール9.4必要オブジェクトの要素は複数回初期化されてはならない
ルール9.5必要指定された初期化子が配列オブジェクトの初期化に使用されている場合、配列のサイズは明示的に指定されなければならない
<実質的な型モデル>
分類項番カテゴリガイドライン
ルール10.1必要オペランドが不適切な実質的な型であってはならない
ルール10.2必要実質的に文字型の式は、加算と減算操作で不適切に使用してはならない
ルール10.3必要式の値はより狭い実質的な型または異なる実質的な型分類でオブジェクトに代入してはならない
ルール10.4必要通常の算術変換が実行される演算子の両方のオペランドは同じ実質的な型分類を持たなければならない
ルール10.5推奨式の値は不適切な実質的な型にキャストしてはならない
ルール10.6必要複合式の値を、より広い実質的な型のオブジェクトに代入してはならない
ルール10.7必要複合式が通常の算術変換が実行される演算子の1つのオペランドとして使用されている場合、もう一方のオペランドは、より広い実質的な型を持ってはいけない
ルール10.8必要複合式の値は異なる実質的な型分類やより広い実質的な型にキャストしてはならない
<ポインタ型の変換>
分類項番カテゴリガイドライン
ルール11.1必要変換は関数へのポインタと任意の他の型との間で行われてはならない
ルール11.2必要変換は不完全な型へのポインタと任意の他の型との間で行われてはならない
ルール11.3必要キャストはオブジェクト型へのポインタ型と別のオブジェクト型へのポインタとの間で行われてはならない
ルール11.4推奨変換はオブジェクトへのポインタと整数型との間で行われてはいけない
ルール11.5推奨変換はvoidへのポインタからオブジェクトへのポインタに行われてはいけない
ルール11.6必要キャストはvoidへのポインタと算術型との間で行われてはならない
ルール11.7必要キャストはオブジェクトへのポインタと非整数算術型との間で行われてはならない
ルール11.8必要キャストはポインタによって指さされた型から任意のconstまたはvolatile修飾を削除してはならない
ルール11.9必要マクロNULLは整数ヌルポインタ定数の形式のみ許されなければならない
<式>
分類項番カテゴリガイドライン
ルール12.1推奨式の中の演算子の優先順位は明白でなければならない
ルール12.2必要シフト演算子の右側のオペランドは、0以上で、左側のオペランドの実質的な型のビット幅未満でなければならない
ルール12.3推奨コンマ演算子を使用してはならない
ルール12.4推奨定数式の評価は、符号なし整数のラップアラウンドを引き起こしてはならない
<副作用>
分類項番カテゴリガイドライン
ルール13.1必要初期化リストは永続的な副作用を含んではならない (補足)
ルール13.2必要式の値とその永続的な副作用は、すべての許可された評価順で同じでなければならない
ルール13.3推奨インクリメントまたはデクリメント演算子を含む完全な式はインクリメントまたはデクリメント演算子に起因するもの以外、他の潜在的な副作用があってはならない
ルール13.4推奨代入演算子の結果を使用してはならない
ルール13.5必要&&や||の論理演算子の右側のオペランドは、永続的な副作用を含んではならない
ルール13.6義務sizeof演算子のオペランドは潜在的な副作用を持っている任意の式を含んではならない
<制御文の式>
分類項番カテゴリガイドライン
ルール14.1必要ループカウンタは、実質的に浮動小数点型を持ってはいけない
ルール14.2必要forループは適正に定義されなければならない
ルール14.3必要制御式は不変であってはならない
ルール14.4必要if文の制御式と繰り返し文の制御式は、実質的にBoolean型を持たなければならない
<制御フロー>
分類項番カテゴリガイドライン
ルール15.1推奨goto文を使用してはならない
ルール15.2必要goto文は、同じ関数のより後ろで宣言されたラベルにジャンプしなければならない
ルール15.3必要goto文によって参照されるラベルは、同じブロック内、またはgoto文を囲む任意のブロック内で宣言されなければならない
ルール15.4推奨繰り返し文を終了するために使用されるブレーク文またはgoto文は1個以下でなければならない
ルール15.5推奨関数は、その最後に1つだけの出口を持たなけらばならない
ルール15.6必要反復文や選択文の本体は、複合文でなければならない
ルール15.7必要すべてのif ... else if構文は、else文で終了しなければならない
<switch文>
分類項番カテゴリガイドライン
ルール16.1必要すべてのswitch文は適正に定義されなければならない
ルール16.2必要スイッチのラベルは、それを直接内包している複合文がswitch文の本体である場合にのみ使用されなければならない
ルール16.3必要無条件のbreak文で、すべてのスイッチ節を終了しなければならない
ルール16.4必要すべてのswitch文は、デフォルトのラベルをもたなければならない
ルール16.5必要デフォルトのラベルは、switch文の最初または最後いずれかのスイッチのラベルとしなければならない
ルール16.6必要すべてのswitch文は、少なくとも2つのスイッチ節を持たなければならない
ルール16.7必要スイッチ式は実質的にブール型を持ってはいけない
<関数>
分類項番カテゴリガイドライン
ルール17.1必要<stdarg.h>の特色を使用してはならない (補足)
ルール17.2必要関数は、直接的または間接的に、自分自身を呼び出しはいけない
ルール17.3義務関数を暗黙的に宣言してはならない
ルール17.4義務void以外の戻り値の型を持つ関数からのすべての出口は式を伴った明示的なreturn文を持たなければならない
ルール17.5推奨配列型を持つように宣言されたパラメータに対応する関数の引数は、要素の適切な数を持たなければならない
ルール17.6義務配列パラメータの宣言は、[ ]の間に静的キーワードを含んではならない (補足)
ルール17.7必要void以外の戻り値の型を持つ関数が返す値は使用されなければならない
ルール17.8推奨関数パラメータを変更してはいけない
<ポインタと配列>
分類項番カテゴリガイドライン
ルール18.1必要ポインタオペランドの算術に起因するポインタはそのポインタのオペランドと同じ配列の要素を処理しなければならない
ルール18.2必要ポインタ間の減算は、同じ配列の要素を扱うポインタにのみ適用されなければならない
ルール18.3必要関係演算子>、>=、<と<=は、それらが同じオブジェクト内を指している場合を除いて、ポインタ型のオブジェクトに適用してはならない
ルール18.4推奨+、 - 、+=と - =演算子は、ポインタ型の式に適用してはいけない
ルール18.5推奨2段階を超える入れ子のポインタを宣言してはいけない
ルール18.6必要自動記憶域を持つオブジェクトのアドレスを、そのオブジェクトが存在しなくなった後も存在する別のオブジェクトにコピーしてはならない
ルール18.7必要フレキシブル配列メンバを宣言してはいけない
ルール18.8必要可変長配列型を使用してはならない
<重なり合う記憶域>
分類項番カテゴリガイドライン
ルール19.1義務オブジェクトは、重複オブジェクトに代入あるいはコピーされてはならない (補足)
ルール19.2推奨unionキーワードを使用してはならない
<前処理指令>
分類項番カテゴリガイドライン
ルール20.1推奨#include指令に対しては、他の前処理指令やコメントのみが先行しうる
ルール20.2必要「'」、「"」または「\」文字、「/*」または「//」文字列がヘッダファイル名に存在してはならない
ルール20.3必要#include指令の後には<filename>文字列または"filename"文字列のどちらかが続かなくてはならない
ルール20.4必要マクロは、キーワードと同じ名前で定義してはいけない
ルール20.5推奨#undefを使用してはならない
ルール20.6必要前処理指令のように見える字句は、マクロ引数内に存在してはならない
ルール20.7必要マクロパラメータの展開の結果生じる式は、括弧で囲まれなければならない
ルール20.8必要#if前処理指令または#elif前処理指令の制御式は、0または1に評価されなければならない
ルール20.9必要#if前処理指令または#elif前処理指令の制御式で使用されるすべての識別子は、評価の前に#defineされていなければならない
ルール20.10推奨#前処理演算子と##前処理演算子を使用してはならない
ルール20.11必要#演算子の直後に続くマクロパラメータの直後に##演算子を続けてはいけない
ルール20.12必要さらに先のマクロ置換の変換そのものである、#演算子または##演算子のオペランドとして使用されるマクロパラメータは、これらの演算子のオペランドとして使用されなければならない
ルール20.13必要その最初の字句が#である行は、有効な前処理指令でなければならない
ルール20.14必要すべての#else、#elif と#endif 前処理指令は、関連する#if、#ifdef、または#ifndef指令と同じファイルになければならない
<標準ライブラリ>
分類項番カテゴリガイドライン
ルール21.1必要予約済み識別子や予約済みマクロ名に対して#defineや#undefを使用してはならない
ルール21.2必要予約済み識別子またはマクロ名を宣言してはならない
ルール21.3必要<stdlib.h>のメモリ割り当てと解放の機能を使用してはならない
ルール21.4必要標準ヘッダファイル<setjmp.h>を使用してはならない
ルール21.5必要標準ヘッダファイル<signal.h>を使用してはならない
ルール21.6必要標準ライブラリの入力/出力の機能を使用してはならない
ルール21.7必要<stdlib.h>のatof関数、atoi関数、atol関数とatoll関数を使用してはならない
ルール21.8必要<stdlib.h>のライブラリ関数 abort、exit、getenv そしてsystemを使用してはならない
ルール21.9必要<stdlib.h>のライブラリ関数 bsearchとqsortを使用してはならない (補足)
ルール21.10必要標準ライブラリのtimeとdate関数を使用してはいけない (補足)
ルール21.11必要標準ヘッダファイル<tgmath.h>を使用してはならない (補足)
ルール21.12推奨<fenv.h>の例外処理機能を使用してはいけない
<資源>
分類項番カテゴリガイドライン
ルール22.1必要標準ライブラリ関数を用いて動的に得られたすべてのリソースは、明示的に解放されなければならない
ルール22.2義務メモリブロックは、それが標準ライブラリ関数を用いて割り当てられていた場合にのみ、解放されなければならない
ルール22.3必要同じファイルを、同時に異なるストリームで、読取りアクセスと書込みアクセスのためにオープンしてはいけない
ルール22.4義務読み取り専用として開かれたストリームに書き込もうとしてはいけない
ルール22.5義務FILEオブジェクトへのポインタを逆参照してはならない
ルール22.6義務関連したストリームが閉じられた後に、FILEへのポインタの値を使用してはならない

MISRA-Cの概要

MISRA-CとはC言語のためのコーディング・ガイドラインです。ヨーロッパの団体であるMISRAが制定しています。対象は、C言語で記述されたクリティカルなシステム(主に組込み系)です。クリティカルなシステムでは、高い安全性と信頼性が要求されます。また移植性も重要です。MISRA-Cの目的はこれらを確保することです。クリティカルなシステム向けのガイドラインとなっていますが、安全性がさほど求められない分野においてもよく使用されています。ソフトウェアの品質向上のためです。ヨーロッパで制定されたガイドラインですが、日本や北米でも広く普及しています。

MISRAとは

MISRA-Cを制定しているMISRAとはどのような団体でしょうか? MISRAは Motor Industry Software Reliability Association の略です。直訳すると「自動車産業ソフトウェア信頼協会」になるでしょうか。自動車メーカー、部品メーカー、エンジニアリングコンサルタントが連携した団体です。そのミッションは「安全で信頼性の高い自動車システム用ソフトウェア作成のための自動車業界への支援を提供する」こととされています。

MISRAには2014年現在下記メンバが所属しています。

公式サイトによると、MISRAの発足は1990年代初頭だそうです。イギリス政府の「SafeIT」プログラム内のプロジェクトとして発足しました。目的は自動車組込みシステム用ソフトウェア作成のためのガイドライン制定です。1994年11月に車両ベースのソフトウェアのための開発ガイドライン(Development Guidelines for Vehicle Based Software)を公開。このドキュメントは、新しいIEC 61508規格(電気・電子・プログラマブル電子の機能安全に関する国際規格)への初めての自動車産業の解釈でもありました。

「SafeIT」からの資金供給が終わってからも、MISRAは継続されました。その最初の成果がMISRA-Cとなります。MISRA-Cはフォード社とローバー社が作成したC言語サブセットをベースに作成されました。以来、MISRA-Cは、安全関連産業においての、C言語組込みシステムのデファクトスタンダードを目指して継続されています。

MISRA-Cの沿革

MISRA-Cの初版は1998年に発表されました。タイトルは「Guidelines for the use of the C language in vehicle based software」(自動車用ソフトウェアでC言語を利用するための手引き)。通称、MISRA-C:1998と表現されています。ガイドラインには17に区分された127件のルールがあります。そのうち必要ルールは93、推奨ルールは34となっています。解説書としては、日本規格協会から『組込み開発者におくるMISRA-C−組込みプログラミングの高信頼化ガイド』(ISBN 978-4542503342)が出版されています。

2004年10月13日には第2版が公開されました。タイトルは「Guidelines for the use of the C language in critical systems」(クリティカルシステムでC言語を利用するための手引き)です。こちらは通称、MISRA-C:2004と呼ばれています。MISRA-C:1998の運用や研究の結果が反映されています。対象が自動車用ソフトウェアから全ての組込みソフトウェアへと拡大されていることも特徴です。21に区分されたルールが141件あります。そのうち必須ルールは121、推奨ルールは20です。翻訳が公益社団法人自動車技術会(JASO)から『自動車用C言語利用のガイドライン(第2版)』(文献番号tp-01002-06)として出版されています。解説書としては、日本規格協会から出版された『組込み開発者におくるMISRA-C:2004−C言語利用の高信頼化ガイド』(ISBN 978-4542503465)があります。

MISRA-Cの第3版は2013年3月18日に発行されました。通称MISRA-C:2012です。第3版はC99対応のため改訂です。内容の整理や充実化、定義の明確化もなされています。26に区分されており、指針が16件、ルールが143件となっています。MISRA-C:2012から「指針」が加えられています。指針・ルールのうち義務は10、必要は111、推奨は39です。2014年現在、出版された翻訳および解説書はありません。

C言語にとってMISRA-Cは重要

C言語は広く普及しているプログラミング言語です。ハードウェアよりの低水準な処理も記述可能でとても便利です。反面、発見の難しい不具合も多く発生します。コンパイル時や実行時のチェック機能が脆弱などの短所もあります。便利ではあるが安全性に問題ありと判断できます。安全性はMISRA-Cのようなコーディングガイドラインを守ることによりある程度保証可能です。より安全なC言語サブセットを定義するMISRA-Cは完成度も高く、C言語利用者にとって重要なガイドラインと言えるでしょう。

補足

MISRA-C:2012 ルール一覧 では分かりにくい指針・ルールについて下記に補足します。

指針 4.1 実行時の障害は最小限に抑えられなければならない

具体的には、実行時エラーが発生する可能性がある場所に動的なチェックを追加するということです。チェックを検討すべき分野は、オーバフローや0除算などの算術エラー、ポインタ演算、配列の境界エラー、関数のパラメータ、ポインタの参照、動的メモリーの割当などです。また、設計標準、テスト計画、静的解析設定ファイル、コードレビューのチェックリストなど、実行時の障害を最小化するための技術文書を準備しておく必要もあるとされています。

指針 4.5 可視性が重複して、同じ名前空間にある識別子は、表記上明白でなければならない

「可視性が重複した識別子」とは「使用可能な識別子」という理解でよいでしょう。また、C言語には名前空間は4種類あります。「ラベル名」「構造体,共用体及び列挙体のタグ」「構造体又は共用体のメンバ」「その他のすべての識別子」です。「表記上明白」とは、少なくともラテンアルファベットに関しては「以下の変化で識別子が同じにならない」ということです。

指針 4.13 リソースに対する操作を提供するように設計された関数は、適切な順序で呼び出さなければならない

この指針は「リソースを扱う際には、その操作関数を適切な順序で呼び出す必要がある」という意味です。リソースに対する操作を提供する関数群は、だいたい次のような3つの種類に分けられます。

そのため、一連の関数は適切な順序でコールされる必要があるということです。

ルール 1.2 言語拡張を使用してはいけない

言語拡張とは、各コンパイラの設計者等によって独自に決められた、標準の仕様にはない拡張された言語仕様のことです。

ルール 1.3 未定義の動作またはクリティカルな未規定の動作の発生があってはならない

未定義の動作とは、簡単にいうと異常なプログラムの動作のことであり、その動作が規格上定義されていないものです。例としては、整数演算のオーバフローに対する動作などがあります。コンパイル時に指摘されることもありますが、実行時にプログラムの異常を検出せず、予測不能な結果を生じることもあります。そのため厳重な注意が必要です。また、未規定の動作とは、プログラムの動作として2つ以上の可能性があり、どれが実行されるかは規定されないというものです。例えば、関数の実引数の評価順序などです。

ルール 3.2 ラインスプライシングは//コメントで使用してはならない

ラインスプライシングは「\」文字の後に改行文字が続くと発生します。//コメントでラインスプライシングを利用すると次の行までコメントになります。その結果、可読性が低下し、思わぬ不具合を招く可能性が高くなります。

ルール 6.1 ビットフィールドは適切な型で宣言されなければならない

適切なビットフィールド型は次のように定められています。C90においては、unsigned int型またはsigned int型。C99においては、(1)unsigned int型またはsigned int型、(2)それ以外の、処理系によって許可された、明示的な符号付き、または明示的な符号なし整数型、(3)_Bool型。

ルール 6.2 ビットフィールドで名付けられたシングルビットは符号付きの型であってはならない

このルールは、符号付きの型のビットフィールドをビット幅1として宣言することを禁止するルールです。符号付きの型で宣言されたビットフィールドのビット幅は最低でも2ビット必要です。値の他に符号を表す1ビットが必要となるためです。

ルール 8.10 インライン関数は、静的記憶域クラスを使用して宣言されなければならない

インライン関数が、外部リンケージで宣言されていて、同じ翻訳単位で定義されていない場合、その動作は未定義です。外部リンケージで宣言されたインライン関数の呼び出しは、関数の外部定義を呼び出すかもしれませんし、インライン定義を使用するかもしれません。この場合、呼び出された関数の動作に変わりはありませんが、実行タイミングには影響があります。そのため、リアルタイム・プログラムにおいては影響が出てしまう可能性があります。異なる翻訳単位で同じインライン関数を使用する場合は、インライン関数をヘッダファイルで定義するとよいでしょう。

ルール 8.14 restrict型修飾子を使用してはならない

restrict修飾された複数のポインタは、それぞれが同じオブジェクトを指していないことを意味します。ristrictはコンパイラの最適化を助けるための型修飾子です。全てのrestrict修飾子を削除してもプログラムの意味は変わりません。restrict修飾子を使用するには、プログラマが複数のポインタによって操作されるメモリ領域が重ならないことを保証する必要があります。restrictの誤用は、期待どおりには動作しないコードの生成につながります。そのため、MISRA-C:2012は、restrict型修飾子の使用を禁止しています。

ルール 13.1 初期化リストは永続的な副作用を含んではならない

このルールは、集成体型の自動オブジェクトの初期化子に実行時に評価される式を含む場合、その式の評価で副作用を発生させてはいけないというルールです。初期化リスト内の式の評価中に発生する副作用の順序は定義されておらず、初期化の動作が予測不明となるからです。

副作用とは、式の評価に際して付随的に実行環境の状態に変化をもたらす効果のことです。ボラタイルオブジェクトへのアクセス、オブジェクトの変更、ファイルの変更、そしてこれらのいずれかの操作を行う関数が副作用となります。また、集成体型とは配列型と構造体型の総称です。集成体型には共用体型は含まれません。

ルール 17.1 <stdarg.h>の特色を使用してはならない

標準規格はstdarg.hに関連した未定義の動作の例を多く挙げています。そのためMISRA-C:2012は、va_list、va_arg、va_start、va_end、va_copyの使用を禁止しています。

ルール 17.6 配列パラメータの宣言は、[ ]の間に静的キーワードを含んではならない

C99では配列パラメータでstaticキーワードを使うことにより、渡す配列の最小要素数を保証することができます。


void func(int ary[static 10])
{
    // 略
}

上記の例では、配列aryは最低10個の要素を含む必要があります。この仕様はコンパイラの最適化を助けます。しかし、指定した最小要素数より要素数が少ない配列をパラメータとして渡してしまった場合、その時の動作は未定義です。MISRA-C:2012は、コードの最適化よりも安全性を重視して、配列パラメータ宣言の[ ]内でのstaticキーワード使用を禁止しています。

ルール 19.1 オブジェクトは、重複オブジェクトに代入あるいはコピーされてはならない

メモリ上で一部が重なり合っている2つのオブジェクトがある状態で、一方のオブジェクトをもう一方のオブジェクトに代入した時の動作は未定義です。また、memmove以外のライブラリ関数を使って上記のような重なり合うオブジェクト間でコピーを行った時の動作も未定義です。そのためルール19.1が制定されています。

このルールには、例外が2つあると記されています。

ルール 21.9 <stdlib.h>のライブラリ関数 bsearchとqsortを使用してはならない

bsearchおよびqsortからコールされる比較関数が対象となっている配列の内容を変更した場合、その動作は未定義です。また、比較関数が首尾一貫した比較結果を返さない場合の動作も未定義です。そのため、ルール21.9が存在します。

bsearchに渡される配列内にキーと等しいと判定される要素が2つある場合、bsearchがどちらを返すかは未規定の動作です。また、qsortに渡される配列内に等しいと判定される要素が2つある時、整列された配列内でのそれらの順序は未規定です。これらの未規定の動作については、比較関数で0を返さないようにすれば回避できます。例えば、要素が等しいと判断される場合は初期状態の配列の格納順で大小を決めるなどすれば、比較関数で0を返さずに済みます。

ルール 21.10 標準ライブラリのtimeとdate関数を使用してはいけない

time.hにより提供される時刻や日付の関数は便利です。しかし、これらは未規定の動作や未定義の動作、処理系定義の動作を含みます。そのため、MISRA-C:2012はこれらの使用を禁止しています。

time.hではありませんが、wchar.hのwcsftime関数の使用も禁止されています。

ルール 21.11 標準ヘッダファイル<tgmath.h>を使用してはならない

tgmath.hで定義される型総称マクロを誤って使用すると、未定義の動作が発生します。そのため、MISRA-C:2012はtgmath.hの使用を禁止しています。

C言語ホーム > その他、C言語の詳細について > MISRA-C前ページ次ページ
© 2014 C言語サイト管理人