Replacing text macros

From Cppreference

Jump to: navigation, search

The preprocessor supports text macro replacement. Function-like text macro replacement is also supported.

Contents

[edit] Syntax

#define identifier replacement-list (1)
#define identifier( parameters ) replacement-list (2)
#define identifier( parameters, ... ) replacement-list (3)
#define identifier( ... ) replacement-list (4)
#undef identifier (5)

[edit] Explanation

[edit] #define directives

The #define directives define the identifier as macro, that is instruct the compiler to replace all successive occurrences of identifier with replacement-list, which can be optionally additionally processed. If the identifier is already defined as any type of macro, the program is ill-formed.

[edit] Object-like macros

Object-like macros replace every occurrence of defined identifier with replacement-list. Version (1) of the #define directive behaves exactly like that.

[edit] Function-like macros

Function-like macros replace each occurrence of defined identifier with replacement-list, additionally taking a number of arguments, which then replace corresponding occurrences of any of the parameters in the replacement-list. The number of arguments must be the same as the number of arguments in macro definition (parameters) or the program is ill-formed. If the identifier is not in functional-notation, i.e. does not have parentheses after itself, it is not replaced at all.

Version (2) of the #define directive defines a simple function-like macro.

Version (3) of the #define directive defines a function-like macro with variable number of arguments. The additional arguments can be accessed using __VA_ARGS__ identifier, which is then replaced with arguments, supplied with the identifier to be replaced.

Version (4) of the #define directive defines a function-like macro with variable number of arguments, but no regular arguments. The arguments can be accessed only with __VA_ARGS__ identifier, which is then replaced with arguments, supplied with identifier to be replaced.

[edit] # and ## operators

An # operator before an identifier in the replacement-list of function-like macro puts in quotes the text, resulting from the identifier after the parameter replacement step.

An ## operator between any two successive identifiers in the replacement-list concatenates two pieces of text, resulting from the identifiers after the parameter replacement step.

[edit] #undef directive

The #undef directive undefines the identifier, that is cancels previous definition of the identifier by #define directive. If the identifier does not have associated macro, the directive is ignored.

[edit] Predefined macros

__cplusplus defined only when compiling C++ program
__STDC_HOSTED__ 1 if the implementation is hosted implementation, 0 otherwise
__DATE__ the date of the compilation in "Mmm dd yyyy" format. Names of the months are the same as generated by the std::asctime() function. If the date is unavailable, implementation-defined date is returned.
__TIME__ the time of the compilation in "hh:mm:ss" format. If the time is unavailable, implementation-defined time is returned
__FILE__ the name of the compiled source file
__LINE__ the line number of the current source line in the current source file

The value of these macros (except for __FILE__ and __LINE__) remain constant throughout the translation unit. Attempts to redefine or undefine these macros result in undefined behavior.

[edit] Example

#include <iostream>
 
//make function factory and use it
#define FUNCTION(name, a) int fun_##name() { return a;}
 
FUNCTION(abcd, 12);
FUNCTION(fff, 2);
FUNCTION(kkk, 23);
 
#undef FUNCTION
#define FUNCTION 34
#define OUTPUT(a) std::cout << #a << '\n'
 
int main()
{
    std::cout << "abcd: " << fun_abcd() << '\n';
    std::cout << "fff: " << fun_fff() << '\n';
    std::cout << "kkk: " << fun_kkk() << '\n';
    std::cout << FUNCTION << '\n';
    OUTPUT(million);               //note the lack of quotes
}

Output:

abcd: 12
fff: 2
kkk: 23
34
million