A call that runs twice
Consider `#define square_macro(X) (X*X)`. The invocation `square_macro(count())` expands to `(count()*count())`: `count()` runs twice, not once. An inline function taking an `unsigned` parameter evaluates the argument once and provides a typed interface. Prefer that function when the number and types of arguments are known. section 17.0
A function-like macro is invoked with parentheses and arguments, but its replacement is source text, not a function call. A replacement can use an argument more than once or interact with surrounding syntax. Even a C library interface specified as a function may be implemented as a macro. section 8.1.2 section 10.2.1
TAKEAWAY: Make a function-like macro behave syntactically like a function call.
- Parenthesize parameters and replacement expressions so surrounding operators do not bind unexpectedly. section 10.2.1
- Do not duplicate an argument that may have side effects; each use in the replacement performs those effects again. section 10.2.1
- Check how the replacement behaves beside `if` and `else`, trailing semicolons, and commas. A macro that looks like one statement can otherwise change the surrounding control flow. section 10.2.1
#define ERROR_RETURN(CODE) \
do { \
if (CODE) return -1; \
} while (false)
The `do { ... } while (false)` wrapper makes a returning macro behave as one statement, avoiding the dangling-`else` problem caused by a bare `if` in its replacement. section 10.2.1
Macros remain useful when a function cannot express the intended interface. They can add compile-time argument checks, provide variable-argument or type-generic interfaces, supply default arguments, and capture information from the invocation site. For example, placing empty string literals around a macro argument accepts a string literal but makes an ordinary character-array name invalid in that position. section 17.0 section 17.2
Tracing is another use of invocation context: `__LINE__`, `__FILE__`, and `__func__` can identify where output originated. Such context access is valuable for debugging but usually undesirable for ordinary functionality, where a function keeps caller and callee separate. Do not assume a `__LINE__` value always fits in an `int`. section 17.3


