[C/C++] User-defined Macro(2): Advanced
Abstract
This post explores advanced macro techniques in C and C++, including stringification (#), token pasting (##), conditional compilation directives, variadic macros, and predefined debugging macros.
1. Introduction
Beyond simple constants and function-like macros, the C preprocessor provides powerful metaprogramming features.
Stringification and token pasting enable dynamic identifier and string creation; conditional directives (#ifdef, #ifndef, #undef) control compilation flow; variadic macros (__VA_ARGS__) support flexible argument lists; and predefined macros (__FILE__, __LINE__, __func__) aid in debugging and diagnostics.
2. Organization
- Token Pasting and Stringification —
#and##operators - Conditional Compilation —
#ifdef,#ifndef,#undef - Variadic Macros —
__VA_ARGS__and comma-swallowing - Predefined Debugging Macros —
__FILE__,__LINE__,__func__ - Previous — Link to the basic macro features post
3. Sections
3.1. Stringification and Token Pasting
The # operator converts an argument into a string constant as shown below:
Click Run ▶
Simillarly, ## operator pastes token to one identifier.
Click Run ▶
3.2. Conditional Compilation
Macros can also be used for conditional branching using preprocessor directives.
The #ifndef directive means:
“if this identifier has not been defined.”
This allows you to define a macro only if it hasn’t been defined elsewhere–useful to ensuring consistent values across multiple files.
1
2
3
#ifndef PI
#define PI 3.141592
#endif
Simillarly, the #ifdef directive means:
“if this identifier has been defined.”
1
2
3
4
5
#define DEBUG
#ifdef DEBUG
printf("Debug mode is on.\n");
#endif
To undefine a macro, use the #undef directive:
#undef identifier.
3.3. Variadic Macros
Variadic macros are function-like macros that accept a variable number of arguments.
Click Run ▶
The ...(ellipsis) is replaced by the special identifier __VA_ARGS__, which gets expanded into the variable arguments passed to the macro.
__VA_ARGS__ is especially useful for writing flexible debugging macros:
Click Run ▶
However, this version will cause a compile error if no arguments are passed for __VA_ARGS__ as below shown:
Click Run ▶
To fix it, use ##__VA_ARGS__ instead, which removes the preceding comma if no arguments follow:
Click Run ▶
In this example, ##__VA_ARGS__ ensures that the comma is safely removed if VA_ARGS is empty.
3.4. Predefined Debugging Macros
You can also use standard predefined macros to show contextual information like the file name, line number, or function name:
__FILE__: Expands to the current file name__LINE__: Expands to the current line number__func__: Expands to the name of the current function
Click Run ▶
This is particularly useful for tracing execution or reporting errors during development.
3.5. Previous
Previous: User-defined Macro(1): Basics