A function-like macro is a preprocessor directive that accepts arguments and performs inline text substitution before the compilation phase begins. Unlike standard C functions, macros do not execute at runtime, allocate stack frames, or enforce type safety; they strictly operate via token replacement handled by the C Preprocessor (CPP).Documentation Index
Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt
Use this file to discover all available pages before exploring further.
Syntax
MACRO_NAME and the opening parenthesis (. If a space is present, the preprocessor interprets it as an object-like macro, treating the parenthesis and parameters as part of the literal replacement_list.
Variadic Macros: The ellipsis (...) indicates a variable number of arguments. Within the replacement_list, these variadic arguments are accessed and substituted using the special identifier __VA_ARGS__.
Preprocessor Mechanics
When the CPP encounters a macro invocation, it performs the following sequence:- Identifies the macro identifier and parses its arguments.
- Argument Prescan: Each argument is fully macro-expanded in isolation before being substituted into the
replacement_list. Exception: Arguments that are operands to the stringification (#) or token pasting (##) operators bypass this prescan phase and are not expanded. - Substitutes the expanded arguments into the corresponding parameters within the
replacement_list. - Replaces the original macro invocation in the source code with the expanded
replacement_list. - Rescans the newly expanded text for further macro expansions.
Special Preprocessor Operators
Macros frequently utilize two preprocessor operators to manipulate tokens during the expansion phase:Stringification (#)
Exclusive to function-like macros, the # operator converts a macro parameter into a string literal. It escapes embedded quotes and backslashes automatically.
Token Pasting (##)
Available in both function-like and object-like macros, the ## operator concatenates two adjacent tokens into a single, valid C token. It is evaluated before the rescanning phase.
Structural Integrity and Pitfalls
Because macros are naive text substitutions, they are highly susceptible to precedence anomalies, evaluation errors, and scope leaks. Understanding these mechanical flaws is critical for writing safe macros.1. Operator Precedence Inversion
Arguments passed to a macro can contain operators. If parameters in thereplacement_list are not strictly parenthesized, the surrounding expression context will alter the intended order of operations.
2. Multiple Evaluation (Side Effects)
If a parameter appears multiple times in thereplacement_list, the argument passed to it will be evaluated multiple times. This causes undefined or unintended behavior if the argument contains side effects (e.g., increment operators, function calls, or volatile reads).
3. Multi-Statement Macros and Scope
When a macro contains multiple statements, expanding it inside control flow structures (like an unbracedif statement) breaks the Abstract Syntax Tree (AST) logic. To safely encapsulate multiple statements, macros are wrapped in a do { ... } while(0) construct. This ensures the macro expands into a single statement block that absorbs a terminating semicolon.
4. Variable Capture (Macro Hygiene)
Even when safely wrapped in ado { ... } while(0) block, macros that declare local variables are vulnerable to variable capture (a lack of macro hygiene). If the caller passes an argument with the exact same identifier as the macro’s internal variable, it results in shadowing or undefined behavior.
int tmp = (tmp); initializes the local variable with its own uninitialized value, destroying the intended logic. Mitigating this in standard C requires using highly obscure naming conventions for internal macro variables (e.g., _swap_internal_tmp_) to minimize collision probability.
Master C with Deep Grasping Methodology!Learn More





