MISRA C:2012 Dir 4.9
A function should be used in preference to a function-like macro where they are interchangeable
説明
命令の定義
A function should be used in preference to a function-like macro where they are interchangeable 1 .
根拠
可能な場合には、マクロの代わりに関数を使用します。関数は引数タイプのチェックと引数の評価を 1 回のみ行い、複数の潜在的な二次的影響を含む問題を回避します。
Polyspace 実装
コード内でマクロが少なくとも 1 回使用され、そのマクロが関数によって置換される可能性がある場合、Polyspace® はこのルールに対する違反を報告します。Polyspace は、以下のいずれかの条件が当てはまる場合、関数によってマクロが置換されることはないと仮定します。
マクロが連結を使用して、関数を定義するか、関数の呼び出しを生成する。たとえば、マクロ
MYFUNCでは、マクロ パラメーターnameを使用して、新しい関数をインラインで作成できるようになっています。Polyspace は、関数によってMyFuncが置換されることはないと仮定し、違反を報告しません。マクロ//Noncompliant #define DH(x) do { printf("using variable = %d\n", x);} while(0) //Compliant #define MYFUNC(name) void myFunc_##name(){printf("call to function\n");}DHが、関数を定義していないか、関数の呼び出しを生成しない。Polyspace は、このマクロは関数によって置換される可能性があると仮定し、違反を報告します。マクロがキーワード
return、goto、labelを使用して制御フローを中断する。キーワードbreakの使用、あるいはswitchブロックまたはループ外部でのキーワードcontinueの使用も、関数によってマクロが置換されることはないことを示します。たとえば、マクロRETURN_NUMは値を返します。マクロCASESに、switchまたは loop ステートメント外部のbreak識別子が含まれている。Polyspace は、これらのマクロが関数によって置換されることはないと仮定します。#define RETURN_NUM(x) do { \ an_uint32 += x; \ return 10; \ } while(0) #define CASES_(x) \ case 0: \ printf("0\n"); \ break; \ case 1: \ printf("1\n"); \ break; \ default: \ printf("default\n");マクロが、そのマクロ内で使用されない変数を少なくとも 1 つ宣言している。たとえば、マクロ
DECLARE_AND_INITIALIZE_VARは 3 つの整数を宣言して初期化します。Polyspace は、このマクロが関数によって置換されることはないと仮定します。#define DECLARE_AND_INITIALIZE_VAR(x, y, z) \ int8_t x = 1; \ int8_t y = x + 1; \ int8_t z = y + 1;マクロが次のシンボルおよびキーワードのいずれかを使用している:
#、__LINE__、__FILE__、_Generic。少なくとも 1 つのマクロのパラメーターが、マクロの本体で型として使用されている。たとえば、マクロ
DECLARATIONおよびCONVERSIONのそれぞれが、本体内でそのいずれかのパラメーターを型として使用しています。Polyspace は、これらのマクロが関数によって置換されることはないと仮定します。#define DECLARATION(x, T) do { \ const T y = x; \ an_uint32 += y; \ } while(0) #define CONVERSION(x, T) ((T) (x))少なくとも 1 つのマクロのパラメーターが演算子または式である。たとえば、マクロ
OPERATIONは演算子を入力として取ります。マクロSTATEMENTは式を入力として取ります。Polyspace は、これらのマクロが関数によって置換されることはないと仮定します。#define OPERATION(x, y, op) ((x) op (y)) #define STATEMENT(x, action) \ if (!x) actionマクロがグローバル変数または
static変数を初期化するために使用される。この目的での関数の呼び出しは許可されません。
トラブルシューティング
ルール違反を想定していてもその違反が表示されない場合、コーディング規約違反が想定どおりに表示されない理由の診断を参照します。
例
チェック情報
| グループ: Code design |
| カテゴリ: 推奨 |
| AGC カテゴリ: 推奨 |
バージョン履歴
R2014b で導入1 All MISRA coding rules and directives are © Copyright The MISRA Consortium Limited 2021.
The MISRA coding standards referenced in the Polyspace Bug Finder™ documentation are from the following MISRA standards:
MISRA C:2004
MISRA C:2012
MISRA C:2023
MISRA C++:2008
MISRA C++:2023
MISRA and MISRA C are registered trademarks of The MISRA Consortium Limited 2021.