13.2 Macros

Preprocessing expands macros in all lines that are not preprocessor directives (lines that do not have a # as the first nonwhite-space character) and in parts of some directives that are not skipped as part of a conditional compilation. (For more information, see “Conditional Compilation”.) The #define directive is typically used to associate meaningful identifiers with constants, keywords, and commonly used statements or expressions. Identifiers that represent constants are called “symbolic constants.” Identifiers that represent statements or expressions are called “macros.” Macros have their own name space. For information, see “Name Spaces” in Chapter 2, on topic .

When the name of the macro is recognized in the program source text or in the arguments of certain other preprocessor commands, it is treated as a call to that macro. The macro name is replaced by a copy of the macro body. If the macro accepts arguments, the actual arguments following the macro name are substituted for formal parameters in the macro body. The process of replacing a macro call with the processed copy of the body is called “expansion” of the macro call.

In practical terms, there are two types of macros. “Object-like” macros take no arguments, while “function-like” macros can be defined to accept arguments so that they look and act like function calls. Because macros do not generate actual function calls, you can make programs run faster by replacing function calls with macros (although C++ inline functions are often a preferred method). However, macros can create problems if you do not define and use them with care. You may have to use parentheses in macro definitions with arguments to preserve the proper precedence in an expression. Also, macros may not correctly handle expressions with side effects. See the getrandom example in “The #define Directive” for more information.

Once you have defined an identifier, you cannot redefine it to a different value without first removing the original definition. However, you can redefine the identifier with exactly the same definition. Thus, the same definition can appear more than once in a program.

The #undef directive removes the definition of an identifier. Once you have removed the definition, you can redefine the identifier to a different value. “The #define Directive” and “The #undef Directive” discuss the #define and #undef directives, respectively.