Main Content

Polyspace Results in Lines Containing Macros

Macros in C/C++ can improve readability and maintainability of code. A macro is a named fragment of code defined with the #define directive, for instance:

#define MAXSIZE 64
The macro name acts as a shorthand for the fragment of code. During preprocessing, each instance of a macro is replaced with its definition. For instance, in the above example, each time you use MAXSIZE, it is replaced with 64 during preprocessing.

Polyspace® provides several conveniences for reviewing results in lines containing macros.

Macros in Source Lines Can Be Expanded in Place

If a source code line contains a macro, the Source pane displays the line with an M icon icon on the left. You can click the icon to expand the macro, that is, see the macro definition, and click again to collapse the macro. See also:

Results in Function-Like Macros Shown Only Once

A function-like macro is a macro that takes parameters, for instance:

#define max(x,y) x>y?x:y
If a function-like macro causes a defect or coding standard violation, the result is displayed on the root cause of the issue: the macro parameter or the macro definition.

For instance:

  • In this example, the definition of macro LEFTOVER() contains a lowercase l and violates MISRA C:2012 Rule 7.3. This result is shown on the macro definition.

    #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);
    }
    
    The event list below the result message shows the instances where the macro is used. You can click an Expansion of macro event to navigate to the macro usage in the source code.

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

  • In this example, the definition of macro COPY_ELEMENT() results in an ambiguous evaluation order and violates MISRA C:2012 Rule 13.2 only when the parameter i++ is passed to it. This result is shown on the macro expansion, specifically on the parameter in the expansion.

    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  */
    }

This way of showing results in function-like macros enables you to easily fix them:

  • For issues caused by the macro definition, you can implement the fix once. Tools that report on the macro expansion can show multiple violations for one root cause.

    In the preceding example, you can change the lowercase l in LEFTOVER() to fix the issue. The REMAINDER() macro shows this fix.

  • For issues caused by the macro parameters, you can also implement the fix once.

    In the preceding example, you can compute i++ in a separate step, and then pass i to the COPY_ELEMENT() macro to fix the issue.