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

The following macro names are predefined in any translation unit.

__cplusplus
expands to value 199711L(until C++11) or 201103L(since C++11)
(macro constant)
__STDC_HOSTED__
(C++11)
expands to the integer constant 1 if the implementation is hosted (runs under an OS), 0 if freestanding (runs without an OS)
(macro constant)
__FILE__
expands to the name of the current file, as a character string literal
(macro constant)
__LINE__
expands to the source file line number, an integer constant
(macro constant)
__DATE__
expands to the date of translation, a character string literal of the form "Mmm dd yyyy". The name of the month is as if generated by std::asctime()
(macro constant)
__TIME__
expands to the time of translation, a character string literal of the form "hh:mm:ss"
(macro constant)

The following additional macro names may be predefined by the implementations.

__STDC__
implementation-defined value, if present
(macro constant)
__STDC_VERSION__
(C++11)
implementation-defined value, if present
(macro constant)
__STDC_ISO_10646__
(C++11)
expands to an integer constant of the form yyyymmL, if wchar_t uses Unicode, the date indicates the latest revision of Unicode supported
(macro constant)
__STDC_MB_MIGHT_NEQ_WC__
(C++11)
expands to 1 if wide character encoding of the basic character set may not equal their narrow encoding
(macro constant)
__STDCPP_STRICT_POINTER_SAFETY__
(C++11)
expands to 1 if the implementation has strict std::pointer_safety
(macro constant)
__STDCPP_THREADS__
(C++11)
expands to 1 if the program can have more than one thread of execution
(macro constant)

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