マクロを含む行での Polyspace の結果
C/C++ のマクロにより、コードの可読性と保守性が向上します。マクロとは、#define
命令を使用して定義されている名前付きコード フラグメントです。次に例を示します。
#define MAXSIZE 64
MAXSIZE
を使用するたびに、前処理中にこれが 64 に置き換えられます。Polyspace® には、マクロを含む行で結果をレビューするために、便利な機能がいくつか用意されています。
ソース行のマクロをインプレースで展開可能
ソース コード行にマクロが含まれている場合、[ソース] ペインでその行の左側に アイコンが表示されます。このアイコンをクリックするとマクロが展開され、マクロ定義を確認できます。もう一度クリックすると、マクロが折りたたまれます。参考:
Bug Finder:
Code Prover:
Polyspace Access Web インターフェイスのソース コード (Polyspace Access)
マクロ展開に複数の Code Prover 実行時チェックが含まれている場合、マクロが折りたたまれている行は、最悪の実行時チェックと同じ色になります。Code Prover の結果とソース コードの色も参照してください。
関数形式のマクロの結果は 1 回のみ表示される
関数形式のマクロとはパラメーターを取るマクロです。次に例を示します。
#define max(x,y) x>y?x:y
次に例を示します。
この例では、マクロ
LEFTOVER()
の定義に小文字のl
が含まれており、これはMISRA C:2012 Rule 7.3
に違反しています。この結果はマクロ定義に表示されます。以下のイベント リストでは、結果のメッセージにマクロが使用されているインスタンスが示されます。[Expansion of macro] イベントをクリックすると、ソース コードのマクロの使用箇所に移動します。#define LEFTOVER(size) 10000ul - size /* Noncompliant */ #define REMAINDER(size) 10000UL - size /* Compliant */ void func(int arrSize, int arrCopySize) { int n = LEFTOVER(arrSize); int nCopy = LEFTOVER(arrCopySize); int m = REMAINDER(arrSize); }
この例では、パラメーター
i++
がマクロCOPY_ELEMENT()
に渡される場合にのみ、このマクロの定義が原因であいまいな評価順序となり、MISRA C:2012 Rule 13.2
に違反します。この結果はマクロ展開の当該パラメーターに示されます。int a[10], b[10]; #define COPY_ELEMENT(index) (a[(index)]=b[(index)]) void main () { int i=0, k=0; COPY_ELEMENT (k); /* Compliant */ COPY_ELEMENT (i++); /* Noncompliant */ }
関数形式のマクロでこのように結果が表示されることで、結果を容易に修正できるようになります。
マクロ定義が原因で発生した問題の場合、修正を 1 回実装できます。マクロ展開上で報告するツールでは、1 つの根本原因に起因する複数の違反が示されることがあります。
前述の例では、
LEFTOVER()
の小文字のl
を変更することでこの問題を修正できます。REMAINDER()
マクロによってこの修正が表示されます。マクロ パラメーターが原因で発生した問題の場合も、修正を 1 回実装できます。
前述の例で問題を修正するには、別のステップで
i++
を計算してからi
をCOPY_ELEMENT()
マクロに渡します。