メインコンテンツ

マクロを含む行での Polyspace の結果

C/C++ のマクロにより、コードの可読性と保守性が向上します。マクロとは、#define 命令を使用して定義されている名前付きコード フラグメントです。次に例を示します。

#define MAXSIZE 64
マクロ名はコード フラグメントの省略表記として機能します。前処理中に、各マクロ インスタンスがその定義に置き換えられます。たとえば上記の例では、MAXSIZE を使用するたびに、前処理中にこれが 64 に置き換えられます。

Polyspace® には、マクロを含む行で結果をレビューするために、便利な機能がいくつか用意されています。

ソース行のマクロをインプレースで展開可能

ソース コード行にマクロが含まれている場合、[ソース] ペインでその行の左側に M icon アイコンが表示されます。このアイコンをクリックするとマクロが展開され、マクロ定義を確認できます。もう一度クリックすると、マクロが折りたたまれます。参考:

関数形式のマクロの結果は 1 回のみ表示される

関数形式のマクロとはパラメーターを取るマクロです。次に例を示します。

#define max(x,y) x>y?x:y
関数形式のマクロが原因で欠陥やコーディング規約違反が発生した場合、結果は問題の根本原因 (マクロ パラメーターまたはマクロ定義) に表示されます。

次に例を示します。

  • この例では、マクロ LEFTOVER() の定義に小文字の l が含まれており、これは MISRA C:2012 Rule 7.3 に違反しています。この結果はマクロ定義に表示されます。

    #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);
    }
    
    以下のイベント リストでは、結果のメッセージにマクロが使用されているインスタンスが示されます。[Expansion of macro] イベントをクリックすると、ソース コードのマクロの使用箇所に移動します。

    Event list below result message points to locations where macro is used.

  • この例では、パラメーター 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++ を計算してから iCOPY_ELEMENT() マクロに渡します。