Macro Substitution

The C++ preprocessor can perform a programmer defined text substitution throughout an entire source code file. This is known as macro substitution. Programmers define a macro using the #define preprocessor directive, which can take the following form.

#define identifier replacement-text

Example 1 General form of a #define directive

Using the #define directive, a programmer declares an identifier and specifies its replacement text. Macro substitution in a source code file involves the preprocessor replacing every occurrence of the identifier with the replacement-text. Listing 2 illustrates macro definition and usage.

1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: #include <iostream>#include <cstdlib> #define MAXIMUM 20 using namespace std; int main(int argc, char* argv[]) { for (int i = 0; i < MAXIMUM; i++) { cout << i << endl; } return EXIT_SUCCESS;}
Listing 2 Macro substitution

We can use macro substitution to implement a constant variable. In the above listing, #define creates an identifier named MAXIMUM, and associates with it the replacement text 20. Anywhere in the program source code that the preprocessor finds MAXIMUM, it replaces with 20. Macro substitution, in this case, allows the identifier MAXIMUM to function as a constant variable.

C++ programmers should use the keyword const instead of macro substitution to create constant variables. Because the keyword const is part of the C++ language (and not a preprocessor feature), constants created with it support type checking better than constants created using macro substitution. Constants created with macro substitution exist in C++ to provide backward compatibility with C programs.

The C++ preprocessor also supports parameterized macros. The use of a parameterized macro looks much like a normal C++ function. The preprocessor replaces the apparent function call with the macro replacement text. A parameterized macro definition takes the following form.

#define identifier(identifier, identifier, ...) replacement-text

Example 2 General form of a parameterized macro

The following listing demonstrates the definition and use of a parameterized macro.

1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: #include <iostream>#include <cstdlib> #define max(x,y) ( ( (x)>(y) ) ? (x):(y) ) using namespace std; int main(int argc, char* argv[]) { int i = 4; int j = 3; cout << max(i, j) << endl; return EXIT_SUCCESS;}
Listing 3 Parameterized macro

In Listing 3, the preprocessor replaces the identifier max with the text "( ( (x)>(y) ) ? (x):(y) )". During the replacement, the preprocessor substitutes into the replacement text the text given as parameters. In line 13, the parameters given are "i" and "j". The preprocessor substitutes this text for the parameters x and y in the replacement text.