...
GNU C (and some other compilers) supported inline functions before they were added to the C Standard and, as a result, have significantly different semantics. Richard Kettlewell provides a good explanation of differences between the C99 and GNU C rules [Kettlewell 2003].
Exceptions
PRE00-C-EX1: Macros can be used to implement local functions (repetitive blocks of code that have access to automatic variables from the enclosing scope) that cannot be achieved with inline functions.
PRE00-C-EX2: Macros can be used for concatenating tokens or performing stringification. For example,
...
calculates only one of the two expressions depending on the selector's value. See PRE05-C. Understand macro replacement when concatenating tokens or performing stringification for more information.
PRE00-C-EX3: Macros can be used to yield a compile-time constant. This is not always possible using inline functions, as shown by the following example:
...
In this example, the ADD_M(3,4)
macro invocation yields a constant expression, but the add_f(3,4)
function invocation does not.
PRE00-C-EX4: Macros can be used to implement type-generic functions that cannot be implemented in the C language without the aid of a mechanism such as C++ templates.
...
Type-generic macros may also be used, for example, to swap two variables of any type, provided they are of the same type.
PRE00-C-EX5: Macro parameters exhibit call-by-name semantics, whereas functions are call by value. Macros must be used in cases where call-by-name semantics are required.
...
Improper use of macros may result in undefined behavior.
Recommendation | Severity | Likelihood | Remediation Cost | Priority | Level |
---|---|---|---|---|---|
PRE00-C | Medium | Unlikely | Medium | P4 | L3 |
Automated Detection
Tool | Version | Checker | Description | ||||||
---|---|---|---|---|---|---|---|---|---|
Astrée |
| macro-function-like | Fully checked | ||||||
Axivion Bauhaus Suite |
| CertC-PRE00 | |||||||
CodeSonar |
| LANG.PREPROC.FUNCMACRO | Function-Like Macro | ||||||
| CC2.PRE00 | Fully implemented | |||||||
Helix QAC |
| C3453 | |||||||
Klocwork |
| MISRA.DEFINE.FUNC | |||||||
LDRA tool suite |
| 340 S | Enhanced enforcement |
Parasoft C/C++test |
| CERT_C-PRE00-a | A function should be used in preference to a function-like macro | ||||||
PC-lint Plus |
| 9026 | Assistance provided | ||||||
Polyspace Bug Finder |
| CERT C: Rec. PRE00-C | Checks for use of function-like macro instead of function (rec. fully covered) | ||||||
RuleChecker |
| macro-function-like function-like-macro-expansion | Fully checked | ||||||
SonarQube C/C++ Plugin |
| S960 |
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
Related Guidelines
SEI CERT C++ Coding Standard | VOID PRE00-CPP. Avoid defining macros |
ISO/IEC TR 24772:2013 | Pre-processor Directives [NMP] |
MISRA C:2012 | Directive 4.9 (advisory) |
Bibliography
[Dewhurst 2002] | Gotcha #26, "#define Pseudofunctions" |
[FSF 2005] | Section 5.34, "An Inline Function Is as Fast as a Macro" |
[Kettlewell 2003] |
[Summit 2005] | Question 10.4 |
...
...