C++ Preprocessor & Macros
In this page:
What is the Preprocessor?
The preprocessor is a distinct text-substitution pass that runs before actual compilation begins. It scans the source file for any line beginning with a hash symbol (#) and processes those directives -- like #include, which literally inserts another file's text at that point -- before the compiler ever sees the resulting code.
Example: What is the Preprocessor?
#include <iostream>
#define GREETING "Hello"
int main() {
std::cout << GREETING << std::endl;
return 0;
}
Login to try C/C++/Java/PHP code in the editor
#define Constants
#define NAME value creates a macro that the preprocessor textually replaces with value everywhere NAME appears in the file afterward. Because this substitution happens before compilation, the compiler never even sees the macro name -- it only sees the expanded result.
Example: #define Constants
#include <iostream>
#define MAX_SCORE 100
int main() {
std::cout << MAX_SCORE << std::endl;
return 0;
}
Login to try C/C++/Java/PHP code in the editor
Function-like Macros
Macros can also accept parameters, letting them behave superficially like functions -- #define SQUARE(x) ((x)*(x)). But because this is pure text substitution with no type checking or scoping, macros can't be overloaded, debugged with normal tools, or trusted the way real functions can.
Example: Function-like Macros
#include <iostream>
#define SQUARE(x) ((x) * (x))
int main() {
std::cout << SQUARE(5) << std::endl;
return 0;
}
Login to try C/C++/Java/PHP code in the editor
Conditional Directives
#ifdef, #ifndef, and #endif let you include or exclude entire blocks of code based on whether a macro has been defined, which is how cross-platform code compiles different implementations for Windows versus Linux, or how header guards prevent a header from being processed twice in one translation unit.
Example: Conditional Directives
#include <iostream>
#define DEBUG_MODE
int main() {
#ifdef DEBUG_MODE
std::cout << "Debug build" << std::endl;
#else
std::cout << "Release build" << std::endl;
#endif
return 0;
}
Login to try C/C++/Java/PHP code in the editor
Macro Parentheses
Because macro substitution is purely textual, failing to parenthesize both the macro's parameters and its overall expression can silently break operator precedence -- #define SQUARE(x) x*x computes the wrong result for SQUARE(a+b), expanding to a+b*a+b instead of the intended (a+b)*(a+b).
Example: Macro Parentheses
#include <iostream>
#define SQUARE_BAD(x) x*x
#define SQUARE_GOOD(x) ((x) * (x))
int main() {
std::cout << SQUARE_BAD(1 + 2) << std::endl;
std::cout << SQUARE_GOOD(1 + 2) << std::endl;
return 0;
}
Login to try C/C++/Java/PHP code in the editor
Chapter Quiz — Complete all 9 topics to unlock
0/9 topics done
Complete these topics first: