...
The documentation for unsafe macros should warn against invoking them with arguments with side effects, but the responsibility is on the programmer using the macro. Because of the risks associated with their use, it is recommended that the creation of unsafe function-like macro macros be avoided (see PRE00-C. Prefer inline or static functions to function-like macros).
...
This compliant solution follows the guidance of PRE00-C. Prefer inline or static functions to function-like macros by defining an inline function iabs() to replace the ABS() macro. Unlike the ABS() macro, which operates on operands of any type, the absiabs() function will truncate arguments of types wider than int whose value is not in range of the latter type.
...
GCC's __typeof extension makes it possible to declare and assign the value of the macro operand to a temporary of the same type and perform the computation on the temporary, consequently guaranteeing that the operand will be evaluated exactly once. Another GCC extension, known as statement expression, makes it possible for the block statement to appear where an expression is expected:
...
The assert() macro is a convenient mechanism for incorporating diagnostic tests in code (see MSC11-C. Incorporate diagnostic tests using assertions). Expressions used as arguments to the standard assert() macro should not have side effects. The behavior of the assert() macro depends on the definition of the object-like macro NDEBUG macro. If the macro NDEBUG is undefined, the assert() macro is defined to evaluate its expression argument and, if the result of the expression compares equal to 0, call the abort() function. If NDEBUG is defined, assert is defined to expand to ((void)0). Consequently, the expression in the assertion is not evaluated, and no side effects it may have had otherwise take place in non-debugging executions of the code.
This noncompliant code example includes an assert macro () macro containing an expression (index++) that has a side effect:
...
This compliant solution avoids the possibility of side effects in assertions by moving the expression containing the side effect outside of the assert macro() macro.
| Code Block | ||||
|---|---|---|---|---|
| ||||
#include <assert.h>
#include <stddef.h>
void process(size_t index) {
assert(index > 0); /* No side effect */
++index;
/* ... */
} |
...