Replacing text macros and the # and ## operators

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

Contents

[hide]

[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 << std::endl int main(){    std::cout << "abcd: " << fun_abcd() << std::endl;    std::cout << "fff: " << fun_fff() << std::endl;    std::cout << "kkk: " << fun_kkk() << std::endl;    std::cout << FUNCTION << std::endl;    OUTPUT(million);               //note the lack of quotes     return 0;}​

Output:

​abcd: 12fff: 2kkk: 2334million​

Advertisements
This entry was posted in Uncategorized. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s