[previous] 3456 [next] Parameter '%s' will be evaluated more than once when this macro is used.
Macro Definition

This macro parameter occurs more than once in the replacement list.

Using a macro parameter more than once can have unexpected consequences if evaluation of the corresponding macro argument induces side effects. This can happen if the argument is an expression containing an assignment, increment or decrement operation, a function call or a reference to a volatile object.

When a function is called, the value of each of the arguments is evaluated before entering the function. When a macro is invoked, each argument simply replaces the corresponding parameter in the replacement list using textual substitution. Confusion may result if the macro argument is an expression which induces side effects and the expression is evaluated more than once.

The dangers associated with using a parameter more than once also depend on the way in which the parameter is used. Message 3456 ignores instances where a parameter is the operand of a # or ## operator because parameter substitution in this context cannot induce side effects. However, message 3435 will always be generated, regardless of context, for any parameter which occurs more than once.

For example:


/*PRQA S 884,3199,3429,3440,3446,3453,3408,3416,3447 ++*/


/***********************************************
 * X is used twice and is not operand to # or ##
 * Y is used twice and is not operand to # or ##
 **********************************************/
#define MAC1(X, Y)   (((X) > (Y)) ? (X) : (Y))              /* Message 3435 + 3456 */


/***********************************************
 * X is used twice but is always an operand to ##
 **********************************************/
#define MAC2(X)      (X ## X)                               /* Message 3435        */


/***********************************************
 * X is used twice but in one case is an operand to #
 **********************************************/
#define MAC3(X)       printf("\"%s\" = %d\n", #X, X)        /* Message 3435        */

extern int r;

extern void foo(int a, int b)
{
    r = MAC1( a++, b++ );                                   /* Message 3454 - One argument will be incremented twice ! */
}

See also:

QA·C Source Code Analyser 8.1.2
© 2013 Programming Research.
www.programmingresearch.com
Personality Groups | Glossary | Message Index Contents