The arguments to a macro should not include preprocessor directives such as {{\#define}}, {{\#ifdef}}, and {{\#include}}.  Doing so is [undefined behavior|BB. Definitions#undefined behavior] according to section 6.10.3.1, paragraph 11 of the C99 standard \[[ISO/IEC 9899:1999|AA. C References#ISO/IEC 9899-1999]\]:
<blockquote><p>The sequence of preprocessing tokens bounded by the outside-most matching parentheses forms the list of arguments for the function-like macro.&nbsp; The individual arguments within the list are separated by comma preprocessing tokens, but comma preprocessing tokens between matching inner parentheses do not separate arguments.&nbsp; <strong>If there are sequences of preprocessing tokens within the list of arguments that would otherwise act as preprocessing directives, the behavior is undefined.</strong></p></blockquote>The scope of this rule includes using preprocessor directives in arguments to a function where it is unknown whether or not the function is implemented using a macro.&nbsp;  For example, standard library functions such as {{memcpy()}}, {{printf()}}, and {{assert()}} may be implemented as macros.

Noncompliant Code Example

In this noncompliant code example \[[GCC Bugs|http://gcc.gnu.org/bugs.html#nonbugs_c]\], the author uses preprocessor directives to specify platform-specific arguments to {{memcpy()}}.&nbsp; However, if {{memcpy()}} is implemented using a macro, the code will result in undefined behavior.&nbsp; For example, this code will compile using GCC version 3.3 and later, but will not compile using GCC versions prior to 3.3 if {{memcpy()}} is a macro.

   memcpy(dest, src,
#ifdef PLATFORM1
	 12
#else
	 24
#endif
	);

Compliant Code Example

In this compliant solution \[[GCC Bugs|http://gcc.gnu.org/bugs.html#nonbugs_c]\], the appropriate call to {{memcpy()}} is determined outside the function call.

#ifdef PLATFORM1
   memcpy(dest, src, 12);
#else
   memcpy(dest, src, 24);
#endif

Risk Assessment

Improper use of macros may result in undefined behavior.

Recommendation

Severity

Likelihood

Remediation Cost

Priority

Level

PRE32-C

low

unlikely

medium

P2

L3

References

\[[GCC Bugs|http://gcc.gnu.org/bugs.html#nonbugs_c]\] "Non-bugs"
\[[ISO/IEC 9899:1999|AA. C References#ISO/IEC 9899-1999]\] Section 6.10.3.1, "Argument substitution," paragraph 11