安全でないマクロへの引数の二次的影響
複数回評価されるか、評価されない可能性のある引数が含まれたマクロ
説明
この欠陥は、二次的影響のある式を含む安全でないマクロを呼び出した場合に発生します。
安全でないマクロ: 展開時に、安全でないマクロは引数を複数回評価したり、まったく評価しなかったりします。
たとえば、
ABSマクロは引数xを 2 回評価します。#define ABS(x) (((x) < 0) ? -(x) : (x))
二次的影響: 評価されると、二次的影響のある式はその式内の 1 つ以上の変数を変更します。
たとえば、
++nはnを変更しますが、n+1はnを変更しません。チェッカーは、入れ子にされたマクロ内の二次的影響を考慮しません。また、チェッカーは関数呼び出しや volatile 変数アクセスを二次的影響と見なしません。
リスク
二次的影響のある式を含む安全でないマクロを呼び出すと、その式は複数回評価されたり、まったく評価されなかったりします。二次的影響は複数回発生する場合もあれば、一切発生しない場合もあり、予期しない動作の原因になります。
たとえば、呼び出し MACRO(++n) では、変数 n が 1 回のみインクリメントされることを想定します。MACRO が安全でないマクロの場合、インクリメントは複数回発生したり、まったく発生しなかったりします。
デバッグ モード以外では assert マクロが無効にされるため、チェッカーは、assert マクロ内の二次的影響を含む式にはフラグを設定します。デバッグ モード以外でコンパイルするには、コンパイル中に NDEBUG マクロを定義します。たとえば、GCC でフラグ -DNDEBUG を使用します。
修正方法
別のステートメントで二次的影響のある式を評価してから、その結果をマクロ引数として使用します。
たとえば、以下のようにはしません。
MACRO(++n);
++n; MACRO(n);
チェッカーは、マクロ本体のブロック スコープ内でのみ定義されたローカル変数の変更を二次的影響と見なします。この欠陥は、変数がマクロ本体内でのみ可視であるため発生しません。この種類の欠陥が表示された場合は、欠陥を無視します。
例
結果情報
| グループ: プログラミング |
| 言語: C | C++ |
| 既定値: オフ |
コマンド ライン構文: SIDE_EFFECT_IN_UNSAFE_MACRO_ARG |
| 影響度: Medium |
バージョン履歴
R2018b で導入