Never invoke an unsafe macro with arguments containing assignment, increment, decrement, or function call. An unsafe macro function is one which evaluates a parameter more than once in the code expansion. The documentation for such macros must warn about putting side-effects on the invocation, and the responsibility is upon the programmer using the macro.
Non-Compliant Coding Example
One reliability problem with unsafe macros is side-effects on macro arguments. A typical example the following non-compliant code example which increments n twice:
#define ABS(x) (((x) < 0) ? -(x) : (x)) ABS(++n); /* undefined behavior */
Compliant Solution
One compliant solution is simply not to invoke an unsafe macro with arguments containing assignment, increment, decrement, or function call, as in the following example:
#define ABS(x) (((x) < 0) ? -(x) : (x)) ++n; ABS(n);
A second compliant solution is to declare ABS() as an inline function (see PRE00-A. Prefer inline functions to macros).
inline int abs(int x) {
return (((x) < 0) ? -(x) : (x));
}
abs(++n);
Risk Assessment
Attempting to modify an object multiple times between sequence points may cause that object to take on an unexpected value. This can lead to unexpected program behavior.
Rule |
Severity |
Likelihood |
Remediation Cost |
Priority |
Level |
|---|---|---|---|---|---|
PRE31-C |
1 (medium) |
1 (probable) |
2 (medium) |
P2 |
L3 |
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
References
[[ISO/IEC 9899-1999]] Section 5.1.2.3, "Program execution"
[[Plum 85]] Rule 1-11