Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Macros are dangerous because their use resembles that of real functions, but they have different semantics. C99 adds inline functions to the C programming language. Inline functions should be preferred over macros when they can be used interchangeably. Making a function an inline function suggests that calls to the function be as fast as possible by using, for example, an alternative to the usual function call mechanism, such as inline substitution. (See also guidelines PRE31-C. Avoid side-effects in arguments to unsafe macros, PRE01-C. Use parentheses within macros around parameter names, and PRE02-C. Macro replacement lists should be parenthesized.)

...

Code Block
bgColor#FFCCCC
int a = 81 / ((++i) * (++i) * (++i));

which is undefined. (see See guideline EXP30-C. Do not depend on order of evaluation between sequence points.).

Compliant Solution

When the macro definition is replaced by an inline function, the side effect is executed only once before the function is called.

...

Wiki Markup
In this noncompliant code example, the programmer has written a macro called {{EXEC_BUMP()}} to call a specified function and increment a global counter \[[Dewhurst 022002|AA. Bibliography#Dewhurst 02]\].  When the expansion of a macro is used within the body of a function, as in this example, identifiers refer to the declarations in scope where the body occurs.  As a result, when the macro is called in the {{aFunc()}} function, it inadvertently increments a local counter with the same name as the global variable. Note that this example also violates guideline [DCL01-C. Do not reuse variable names in subscopes].

...

This noncompliant code example also violates guideline EXP30-C. Do not depend on order of evaluation between sequence points.

...

Wiki Markup
GNU C (and some other compilers) supported inline functions before they were added to C99 and, as a result, have significantly different semantics.  Richard Kettlewell provides a good explanation of differences between the C99 and GNU C rules \[[Kettlewell 032003|AA. Bibliography#Kettlewell 03]\].

...

calculates only one of the two expressions depending on the selector's value. See guideline PRE05-C. Understand macro replacement when concatenating tokens or performing stringification for more information.

...

An example of the use of function-like macros to create type-generic functions is shown in guideline MEM02-C. Immediately cast the result of a memory allocation function call into a pointer to the allocated type.

...

Recommendation

Severity

Likelihood

Remediation Cost

Priority

Level

PRE00-C

medium

unlikely

medium

P4

L3

Automated Detection

...

Tool

Version

Checker

Description

Section

LDRA tool suite

...

Include Page
c:LDRA_V
c:LDRA_V

 

 

Related Vulnerabilities

Search for vulnerabilities resulting from the violation of this rule on the CERT website.

Other Languages

Related Guidelines

This rule appears in the C++ Secure Coding Standard as : PRE00-CPP. Avoid defining macros.

Bibliography

Wiki Markup
\[[FSF 052005|AA. Bibliography#FSF 05]\] Section 5.34, "[An Inline Function Is as Fast as a Macro|http://gcc.gnu.org/onlinedocs/gcc/Inline.html]"
\[[Dewhurst 022002|AA. Bibliography#Dewhurst 02]\] Gotcha #26, "#define Pseudofunctions"
\[[ISO/IEC 9899:1999|AA. Bibliography#ISO/IEC 9899-1999]\] Section 6.7.4, "Function specifiers"
\[[ISO/IEC PDTR 24772|AA. Bibliography#ISO/IEC PDTR 24772]\] "NMP Pre-processor Directives"
\[[Kettlewell 032003|AA. Bibliography#Kettlewell 03]\]
\[[MISRA 042004|AA. Bibliography#MISRA 04]\] Rule 19.7
\[[Summit 052005|AA. Bibliography#Summit 05]\] Question 10.4

...