You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 13 Next »

The arguments to a macro should not include preprocessor directives such as #define, #ifdef, and #include.  Doing so is undefined behavior according to section 6.10.3, paragraph 11 of the C99 standard [ISO/IEC 9899:1999] (see also undefined behavior 87 of Annex J):
<blockquote><p>The sequence of preprocessing tokens bounded by the outside-most matching parentheses forms the list of arguments for the function-like macro.  The individual arguments within the list are separated by comma preprocessing tokens, but comma preprocessing tokens between matching inner parentheses do not separate arguments.  <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.  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], the author uses preprocessor directives to specify platform-specific arguments to memcpy(). However, if memcpy() is implemented using a macro, the code results in undefined behavior.

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

Compliant Code Example

In this compliant solution [GCC Bugs], 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] "Non-bugs"
[ISO/IEC 9899:1999] Section 6.10.3.1, "Argument substitution," paragraph 11


PRE31-C. Avoid side-effects in arguments to unsafe macros      01. Preprocessor (PRE)      02. Declarations and Initialization (DCL)

  • No labels