Mechanics of Substitution
- Translation Phase: Macro expansion occurs during Translation Phase 4 of the C compilation process. The compiler itself never sees the macro identifier; it only processes the resulting
replacement_list. - Tokenization: The
replacement_listconsists of a sequence of preprocessing tokens (e.g., constants, string literals, operators, or other identifiers). If the list is empty, the identifier is replaced by nothing, effectively removing it from the source code. - Recursive Expansion: If the
replacement_listcontains identifiers of other defined macros, the preprocessor will continually expand them. However, if a macro’s identifier appears within its own expansion, it is not expanded a second time, preventing infinite recursion.
Scope and Lifecycle
- Lexical Scope: The macro becomes active immediately after its
#definedirective and remains valid until the end of the translation unit (source file) or until it is explicitly revoked. - Revocation: The
#undefdirective terminates the macro’s scope.
- Redefinition: An object-like macro cannot be redefined with a different
replacement_listunless it is first undefined. Redefining it with the exact same sequence of tokens (including whitespace equivalence) is permitted by the C standard.
Technical Characteristics
- No Memory Allocation: Because object-like macros are resolved via token substitution prior to compilation, the macro identifiers themselves do not exist at runtime and do not occupy memory addresses.
- Lvalue Evaluation: While the macro identifier itself is strictly a preprocessor construct, its evaluation as an lvalue depends entirely on its
replacement_list. If the substituted tokens form a valid lvalue (e.g.,#define ALIAS global_varor#define DEREF (*ptr)), the expanded macro can be placed on the left side of an assignment operator or referenced with the address-of (&) operator. If the tokens form an rvalue (e.g., a numeric constant), it cannot. - Type Agnosticism: Macros possess no inherent C data type. Type evaluation occurs only after substitution, when the compiler evaluates the resulting expression based on the injected tokens.
- String Literal Independence: The preprocessor will not replace macro identifiers that appear inside string literals or character constants. For example,
printf("IDENTIFIER");remains unchanged regardless of the macro definition.
Tired of Poor C Skills? Fix That With Deep Grasping!Learn More





