Avance.Lab

技術紹介

第3回 MISRA-C ~推奨ルール~

公開日:2022.05.27 更新日:2022.05.27

tag: 組み込み車載

こんにちは、TMIHです。

前回は、MISRA-Cの必要ルールに準拠したプログラムと必要ルールから逸脱したプログラム、必要ルールからの逸脱手順について紹介しました。

今回は、MISRA-Cの推奨ルールに対するプログラムについて、説明したいと思います。

推奨ルールに準拠したプログラム

まずは、MISRA-C:2004の推奨ルールに準拠したプログラムを紹介したいと思います。

ルールNo.12.13
カテゴリー推奨
内容インクリメント演算子及びデクリメント演算子は、式中で他の演算子と混在させるべきではない。
詳細ルール12.13は、以下の理由により、インクリメント演算子及びデクリメント演算子を他の算術演算子と組み合わせて使わないことを推奨する。
 ・コードの可読性を著しく落とす
 ・未規定あるいは未定義のふるまいとなる副作用をコードに取り込んでしまう可能性があるインクリメントとデクリメントは、他の算術演算子とは分離して使う方が安全である。

・サンプルプログラム1

10行目の処理は、インクリメント演算子及びデクリメント演算子と他の演算子が混在しているため、ルール12.13から逸脱していることになります。

void func(void)
{
    unsigned int num1;
    unsigned int num2;
    unsigned int num3;

    num1 = 5;
    num2 = 7;

    num3 = ++num1 + num2--;
}

・サンプルプログラム2

サンプルプログラム1をルール12.13に準拠させたプログラムになります。

10~12行目では1行目でまとめていた処理を切り分けて、インクリメント演算子及びデクリメント演算子と他の演算子を混在しないようにしています。

その結果、ルール12.13に準拠していることになります。

void func(void)
{
    unsigned int num1;
    unsigned int num2;
    unsigned int num3;

    num1 = 5;
    num2 = 7;

    ++num1;
    num3 = num1 + num2;
    num2--;
}

推奨ルールに逸脱したプログラム

次に、MISRA-C:2004の推奨ルールに逸脱したプログラムを紹介したいと思います。

ルールNo.19.7
カテゴリー推奨
内容関数形式マクロよりも関数を用いるべきである。
詳細ルール19.7は、より安全で可読性のよいプログラムにするために、関数形式マクロよりも関数の使用を推奨するものである。
マクロはコンパイル時に展開されるため、関数と比較すると、マクロの方が高速に動作する可能性が高い。しかしその半面、以下のような問題がある。
 ・引数と戻り値の型の指定及びチェックの機構がないため、与える実引数の型によって、正しく動作する場合としない場合がある。関数の場合は、宣言で引数と戻り値の型を指定できる。
関数形式マクロは、関数に変更することで上記のような問題の予防が期待できる。

・サンプルプログラム

2行目で関数形式マクロを定義して8行目で使用しているため、ルール19.7から逸脱していることになります。


#define  MAX(a, b)    ( ( a ) < ( b ) ? ( b ) : ( a ) )

unsigned int func( unsigned int num1, unsigned int num2)
{
    unsigned int ret;

    ret = MAX(num1, num2);

    return(ret);
}

準拠させるには2行目の関数形式マクロを関数へ変更すればよいのですが、
ルールの説明にもある通り、実行速度は関数よりもマクロの方が高速になります。
組み込みの世界では、プログラムの実行速度を求められることは珍しくありません。
少しでも実行速度を早くしたい場面では無理に準拠せず、敢えて逸脱することも一つの手段だと思います。

逸脱する場合、ルール19.7は推奨ルールですので、MISRA-C(第2回)で説明した逸脱説明書を作成する必要はありません。
ただし、ルール19.7で挙げられている問題に対する対策は講じる必要があります。
サンプルプログラムの内容であれば、引数(num1、num2)と戻り値(ret)の型が同じであるため動作を保証できます。

後書き

私が過去に開発に携わったプロジェクトでは、既存のコードをMISRA-Cに準拠させるということを行いました。
そのプロジェクトでは必要ルールは極力準拠し、どうしても従えないルールはやむを得ず逸脱するという方針で開発しました。
推奨ルールの準拠は任意で、対応が難しいまたは効果が薄いようなルールは準拠を見送りました。

C言語用の静的解析ツールを用いてMISRA-Cの逸脱件数を確認しながら対応を進めましたが、対応前の逸脱件数は数千件にのぼりました。
その警告1つ1つを準拠していくのは骨の折れる作業でしたが、対応する中で未発見のバグが見つかることもありました。
MISRA-Cに準拠していれば防ぐことができたバグであったため、MISRA-Cの重要性を改めて実感しました。

MISRA-Cの制限があることで自由なコーディングができなくなってしまうデメリットはありますが、
その分大きなメリットがありますので、準拠していないソースコードがあれば、準拠の検討をしてみてはいかがでしょうか。

引用・参考文献

「組込み開発者におくるMISRA-C:2004 C言語利用の高信頼化ガイド」、MISRA-C 研究会編、ISBN 9784542503342、日本規格協会

TMIH
TMIH

主に組み込み系を担当。食べることが趣味

関連記事