Wiki Markup |
---|
The arguments to a macro should not include preprocessor directives such as {{\#define}}, {{\#ifdef}}, and {{\#include |
memcpy()
, printf()
, and assert()
}}. Doing so is [undefined behavior|BB. Definitions#undefined behavior] \[[ISO/IEC 9899:1999|AA. C References#ISO/IEC 9899-1999]\]. This includes using preprocessor directives in arguments to a function where it is unknown whether or not the function is implemented using a macro. Examples include standard library functions such as {{memcpy()}}, {{printf()}}, and {{assert()}}. |
Noncompliant Code Example
Wiki Markup |
---|
In this noncompliant code example \[[Non-bugs in GCC CBugs|http://gcc.gnu.org/bugs.html#nonbugs_c]\], the author is attempting to specify an argument to {{memcpy()}} depending on the current platform by using preprocessor directives within the function call. However, if {{memcpy()}} is implemented using a macro, the code will result in undefined behavior. For example, this code will compile using GCC version 3.3 and later, but will not compile using GCC versions prior to 3.3. |
Code Block | ||
---|---|---|
| ||
memcpy(dest, src, #ifdef PLATFORM1 12 #else 24 #endif ); |
...
Wiki Markup |
---|
In this compliant solution \[[Non-bugs in GCC CBugs|http://gcc.gnu.org/bugs.html#nonbugs_c]\], the appropriate call to {{memcpy()}} is determined outside the function call. |
Code Block | ||
---|---|---|
| ||
#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 |
---|---|---|---|---|---|
PRE13-C | low | unlikely | medium | P2 | L3 |
References
Wiki Markup |
---|
\[[Non-bugs in GCC CBugs|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, "Macro replacement" |