Movatterモバイル変換


[0]ホーム

URL:


cppreference.com
Namespaces
Variants
    Actions

      Replacing text macros

      From cppreference.com
      <cpp‎ |preprocessor
       
       
      C++ language
      General topics
      Flow control
      Conditional execution statements
      Iteration statements (loops)
      Jump statements
      Functions
      Function declaration
      Lambda function expression
      inline specifier
      Dynamic exception specifications(until C++17*)
      noexcept specifier(C++11)
      Exceptions
      Namespaces
      Types
      Specifiers
      constexpr(C++11)
      consteval(C++20)
      constinit(C++20)
      Storage duration specifiers
      Initialization
      Expressions
      Alternative representations
      Literals
      Boolean -Integer -Floating-point
      Character -String -nullptr(C++11)
      User-defined(C++11)
      Utilities
      Attributes(C++11)
      Types
      typedef declaration
      Type alias declaration(C++11)
      Casts
      Memory allocation
      Classes
      Class-specific function properties
      Special member functions
      Templates
      Miscellaneous
       
       

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

      Contents

      [edit]Syntax

      #defineidentifier replacement-list (optional) (1)
      #defineidentifier (parameters )replacement-list (optional) (2)
      #defineidentifier (parameters , ...)replacement-list (optional) (3)(since C++11)
      #defineidentifier (...)replacement-list (optional) (4)(since C++11)
      #undefidentifier (5)

      [edit]Explanation

      [edit]#define directives

      The#define directives define theidentifier as macro, that is instruct the compiler to replace most successive occurrences ofidentifier withreplacement-list, which will be additionally processed. Exceptions arise from the rules ofscanning and replacement. If the identifier is already defined as any type of macro, the program is ill-formed unless the definitions are identical.

      [edit]Object-like macros

      Object-like macros replace every occurrence of definedidentifier withreplacement-list. Version (1) of the#define directive behaves exactly like that.

      [edit]Function-like macros

      Function-like macros replace each occurrence of definedidentifier withreplacement-list, additionally taking a number of arguments, which then replace corresponding occurrences of any of theparameters in thereplacement-list.

      The syntax of a function-like macro invocation is similar to the syntax of a function call: each instance of the macro name followed by a( as the next preprocessing token introduces the sequence of tokens that is replaced by thereplacement-list. The sequence is terminated by the matching) token, skipping intervening matched pairs of left and right parentheses.

      For version (2), the number of arguments must be the same as the number of parameters in macro definition. For versions (3,4), the number of arguments must not be less than the number of parameters (not(since C++20) counting...). Otherwise 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 (calledvariable 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 (calledvariable arguments) can be accessed only with__VA_ARGS__ identifier, which is then replaced with arguments, supplied with the identifier to be replaced.

      For versions (3,4),replacement-list may contain the token sequence__VA_OPT__(content ), which is replaced bycontent if__VA_ARGS__ is non-empty, and expands to nothing otherwise.

      #define F(...) f(0 __VA_OPT__(,) __VA_ARGS__)F(a, b, c)// replaced by f(0, a, b, c)F()// replaced by f(0) #define G(X, ...) f(0, X __VA_OPT__(,) __VA_ARGS__)G(a, b, c)// replaced by f(0, a, b, c)G(a,)// replaced by f(0, a)G(a)// replaced by f(0, a) #define SDEF(sname, ...) S sname __VA_OPT__(= { __VA_ARGS__ })SDEF(foo);// replaced by S foo;SDEF(bar,1,2);// replaced by S bar = { 1, 2 };
      (since C++20)

      Note: if an argument of a function-like macro includes commas that are not protected by matched pairs of left and right parentheses (most commonly found in template argument lists, as inassert(std::is_same_v<int,int>); orBOOST_FOREACH(std::pair<int,int> p, m)), the comma is interpreted as macro argument separator, causing a compilation failure due to argument count mismatch.

      [edit]Scanning and Replacement
      • Scanning keeps track of macros they replaced. If scan finds text matching such macro, it marks it "to be ignored" (all scans will ignore it). This prevents recursion.
      • If scanning found function-like macro, arguments are scanned before put insidereplacement-list. Except# and## operators take argument without scan.
      • After macro was replaced, result text is scanned.

      Note, it is possible to define pseudo recursive macro:

      Run this code
      #define EMPTY#define SCAN(x)     x#define EXAMPLE_()  EXAMPLE#define EXAMPLE(n)  EXAMPLE_ EMPTY()(n-1) (n)EXAMPLE(5)SCAN(EXAMPLE(5))

      Output:

      EXAMPLE_ ()(5 -1) (5)EXAMPLE_ ()(5 -1 -1) (5 -1) (5)

      [edit]Reserved macro names

      A translation unit thatincludes a standard library header may not#define or#undef names declared in anystandard library header.

      A translation unit that uses any part of the standard library is not allowed to#define or#undef names lexically identical to:

      (since C++11)

      Otherwise, the behavior is undefined.

      [edit]# and## operators

      In function-like macros, a# operator before an identifier in thereplacement-list runs the identifier through parameter replacement and encloses the result in quotes, effectively creating a string literal. In addition, the preprocessor adds backslashes to escape the quotes surrounding embedded string literals, if any, and doubles the backslashes within the string as necessary. All leading and trailing whitespace is removed, and any sequence of whitespace in the middle of the text (but not inside embedded string literals) is collapsed to a single space. This operation is called "stringification". If the result of stringification is not a valid string literal, the behavior is undefined.

      When# appears before__VA_ARGS__, the entire expanded__VA_ARGS__ is enclosed in quotes:

      #define showlist(...) puts(#__VA_ARGS__)showlist();// expands to puts("")showlist(1,"x",int);// expands to puts("1, \"x\", int")
      (since C++11)

      A## operator between any two successive identifiers in thereplacement-list runs parameter replacement on the two identifiers (which are not macro-expanded first) and then concatenates the result. This operation is called "concatenation" or "token pasting". Only tokens that form a valid token together may be pasted: identifiers that form a longer identifier, digits that form a number, or operators+ and= that form a+=. A comment cannot be created by pasting/ and* because comments are removed from text before macro substitution is considered. If the result of concatenation is not a valid token, the behavior is undefined.

      Note: some compilers offer an extension that allows## to appear after a comma and before__VA_ARGS__, in which case the## does nothing when the variable arguments are present, but removes the comma when the variable arguments are not present: this makes it possible to define macros such asfprintf(stderr, format,##__VA_ARGS__).This can also be achieved in a standard manner using__VA_OPT__, such asfprintf(stderr, format __VA_OPT__(,) __VA_ARGS__).(since C++20)

      [edit]#undef directive

      The#undef directive undefines theidentifier, that is cancels previous definition of theidentifier 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 every translation unit:

      __cplusplus
      denotes the version of C++ standard that is being used, expands to value
      • 199711L(until C++11),
      • 201103L(C++11),
      • 201402L(C++14),
      • 201703L(C++17),
      • 202002L(C++20), or
      • 202302L(C++23)
        (macro constant)
      __STDC_HOSTED__
      (C++11)
      expands to the integer constant1 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, can be changed by the#line directive
      (macro constant)
      __LINE__
      expands to the line number of the currentphysical source line, an integer constant, can be changed by the#line directive
      (macro constant)
      __DATE__
      expands to the date of translation, a character string literal of the form"Mmm dd yyyy". The first character of"dd" is a space if the day of the month is less than 10. The name of the month is as if generated bystd::asctime()
      (macro constant)
      __TIME__
      expands to the time of translation, a character string literal of the form"hh:mm:ss"
      (macro constant)
      __STDCPP_DEFAULT_NEW_ALIGNMENT__
      (C++17)
      expands to anstd::size_t literal whose value is the alignment guaranteed by a call to alignment-unawareoperator new (larger alignments will be passed to alignment-aware overload, such asoperator new(std::size_t,std::align_val_t))
      (macro constant)
      __STDCPP_­BFLOAT16_­T____STDCPP_­FLOAT16_­T____STDCPP_FLOAT32_T____STDCPP_FLOAT64_T____STDCPP_FLOAT128_T__
      (C++23)
      expands to1 if and only if the implementation supports correspondingextended floating-point type
      (macro constant)
      __STDC_EMBED_NOT_FOUND____STDC_EMBED_FOUND____STDC_EMBED_EMPTY__
      (C++26)
      expands to0,1 and2 respectively
      (macro constant)

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

      __STDC__
      implementation-defined value, if present, typically used to indicate C conformance
      (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 formyyyymmL, ifwchar_t uses Unicode, the date indicates the latest revision of Unicode supported

      (until C++23)

      implementation-defined value, if present

      (since C++23)

      (macro constant)
      __STDC_MB_MIGHT_NEQ_WC__
      (C++11)
      expands to1 if'x'== L'x' might be false for a memberx of the basic character set, such as on EBCDIC-based systems that use Unicode forwchar_t
      (macro constant)
      __STDCPP_THREADS__
      (C++11)
      expands to1 if the program can have more than one thread of execution
      (macro constant)
      __STDCPP_STRICT_POINTER_SAFETY__
      (C++11)(removed in C++23)
      expands to1 if the implementation has strictstd::pointer_safety
      (macro constant)

      The values 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.

      Language feature-testing macros

      The standard defines a set of preprocessor macros corresponding to C++ language features introduced in C++11 or later. They are intended as a simple and portable way to detect the presence of said features.

      SeeFeature testing for details.

      (since C++20)


      Notes

      Thefunction-local predefined variable__func__ is not a predefined macro, but it is usually used together with__FILE__ and__LINE__, e.g. byassert.

      (since C++11)

      [edit]Example

      Run this code
      #include <iostream> // Make function factory and use it#define FUNCTION(name, a) int fun_##name() { return a; } FUNCTION(abcd,12)FUNCTION(fff,2)FUNCTION(qqq,23) #undef FUNCTION#define FUNCTION 34#define OUTPUT(a) std::cout << "output: " #a << '\n' // Using a macro in the definition of a later macro#define WORD "Hello "#define OUTER(...) WORD #__VA_ARGS__ int main(){std::cout<<"abcd: "<< fun_abcd()<<'\n';std::cout<<"fff: "<< fun_fff()<<'\n';std::cout<<"qqq: "<< fun_qqq()<<'\n'; std::cout<< FUNCTION<<'\n';    OUTPUT(million);//note the lack of quotes std::cout<< OUTER(World)<<'\n';std::cout<< OUTER(WORD World)<<'\n';}

      Output:

      abcd: 12fff: 2qqq: 2334output: millionHello WorldHello WORD World

      [edit]Defect reports

      The following behavior-changing defect reports were applied retroactively to previously published C++ standards.

      DRApplied toBehavior as publishedCorrect behavior
      CWG 2908C++98it was unclear whether__LINE__ expands to the current
      physical line number or the current logical line number
      expands to the current
      physical line number
      LWG 294C++98a translation unit that includes a standard library header could contain
      macros that define names declared in other standard library headers
      prohibited
      P2621R2C++23universal character names were not allowed
      to be formed by token concatenation
      allowed

      [edit]See also

      C++ documentation forMacro Symbol Index
      C documentation forReplacing text macros
      Retrieved from "https://en.cppreference.com/mwiki/index.php?title=cpp/preprocessor/replace&oldid=182196"

      [8]ページ先頭

      ©2009-2025 Movatter.jp