[cpp] (original) (raw)
15 Preprocessing directives [cpp]
15.1 Preamble [cpp.pre]
pp-private-module-fragment:
module : private ; new-line group
lparen:
a ( character not immediately preceded by whitespace
pp-balanced-token:
( pp-balanced-token-seq )
[ pp-balanced-token-seq ]
{ pp-balanced-token-seq }
any pp-token except:
parenthesis (U+0028 left parenthesis and U+0029 right parenthesis),
bracket (U+005b left square bracket and U+005d right square bracket), or
brace (U+007b left curly bracket and U+007d right curly bracket).
new-line:
the new-line character
A preprocessing directive consists of a sequence of preprocessing tokens that satisfies the following constraints: At the start of translation phase 4, the first preprocessing token in the sequence, referred to as a directive-introducing token, begins with the first character in the source file (optionally after whitespace containing no new-line characters) or follows whitespace containing at least one new-line character, and is
- a # preprocessing token, or
- an import preprocessing token immediately followed on the same logical source line by a,<,identifier,string-literal, or:preprocessing token, or
- a module preprocessing token immediately followed on the same logical source line by anidentifier,:, or;preprocessing token, or
- an export preprocessing token immediately followed on the same logical source line by one of the two preceding forms.
The last preprocessing token in the sequence is the first preprocessing token within the sequence that is immediately followed by whitespace containing a new-line character.122
[Note 1:
A new-line character ends the preprocessing directive even if it occurs within what would otherwise be an invocation of a function-like macro.
— _end note_]
[Example 1: # module ; export module leftpad; import <string>; export import "squee"; import rightpad; import :part; module; export importfoo; export import foo; import :: import -> — _end example_]
A sequence of preprocessing tokens is only a text-lineif it does not begin with a directive-introducing token.
[Example 2: using module = int;module i; int foo() { return i;}
The example is not a valid preprocessing-file.
— _end example_]
A sequence of preprocessing tokens is only a conditionally-supported-directiveif it does not begin with any of the directive names appearing after a # in the syntax.
A conditionally-supported-directive is conditionally-supported withimplementation-defined semantics.
Any embed-prefixed-parameter is conditionally-supported, with implementation-defined semantics.
At the start of phase 4 of translation, the group of a pp-global-module-fragment shall contain neither a text-line nor a pp-import.
When in a group that is skipped ([cpp.cond]), the directive syntax is relaxed to allow any sequence of preprocessing tokens to occur between the directive name and the following new-line character.
The only whitespace characters that shall appear between preprocessing tokens within a preprocessing directive (from just after the directive-introducing token through just before the terminating new-line character) are space and horizontal-tab (including spaces that have replaced comments or possibly other whitespace characters in translation phase 3).
The implementation can process and skip sections of source files conditionally, include other source files, import macros from header units, and replace macros.
These capabilities are calledpreprocessing, because conceptually they occur before translation of the resulting translation unit.
The preprocessing tokens within a preprocessing directive are not subject to macro expansion unless otherwise stated.
[Example 3:
In:#define EMPTY EMPTY # include <file.h> the sequence of preprocessing tokens on the second line is _not_a preprocessing directive, because it does not begin with a # at the start of translation phase 4, even though it will do so after the macro EMPTYhas been replaced.
— _end example_]
15.2 Conditional inclusion [cpp.cond]
has-include-expression:
__has_include ( )
__has_include ( )
has-attribute-expression:
__has_cpp_attribute ( pp-tokens )
The expression that controls conditional inclusion shall be an integral constant expression except that identifiers (including those lexically identical to keywords) are interpreted as described below123and it may contain zero or moredefined-macro-expressions,has-include-expressions,has-attribute-expressions, and/or has-embed-expression_s_as unary operator expressions.
A defined-macro-expression evaluates to 1if the identifier is currently defined as a macro name (that is, if it is predefined or if it has one or more active macro definitions ([cpp.import]), for example because it has been the subject of a#definepreprocessing directive without an intervening#undefdirective with the same subject identifier), 0 if it is not.
The second form of has-include-expressionis considered only if the first form does not match, in which case the preprocessing tokens are processed just as in normal text.
The header or source file identified by the parenthesized preprocessing token sequence in each contained has-include-expressionis searched for as if that preprocessing token sequence were the pp-tokens in a #include directive, except that no further macro expansion is performed.
If such a directive would not satisfy the syntactic requirements of a #include directive, the program is ill-formed.
The has-include-expression evaluates to 1 if the search for the source file succeeds, and to 0 if the search fails.
The parenthesized pp-balanced-token-seq in each containedhas-embed-expression is processed as if thatpp-balanced-token-seq were the pp-tokens in the third form of a #embed directive ([cpp.embed]).
If such a directive would not satisfy the syntactic requirements of a#embed directive, the program is ill-formed.
The has-embed-expression evaluates to:
- __STDC_EMBED_FOUND__ if the search for the resource succeeds, all the given embed-parameters in the embed-parameter-seqare supported, and the resource is not empty.
- Otherwise, __STDC_EMBED_EMPTY__ if the search for the resource succeeds, all the given embed-parameters in the embed-parameter-seqare supported, and the resource is empty.
- Otherwise, __STDC_EMBED_NOT_FOUND__.
[Note 1:
An unrecognized embed-parameter in an has-embed-expressionis not ill-formed and is instead treated as not supported.
— _end note_]
Each has-attribute-expression is replaced by a non-zero pp-numbermatching the form of an integer-literalif the implementation supports an attribute with the name specified by interpreting the pp-tokens, after macro expansion, as an attribute-token, and by 0 otherwise.
The program is ill-formed if the pp-tokensdo not match the form of an attribute-token.
For an attribute specified in this document, it is implementation-defined whether the value of the has-attribute-expressionis 0 or is given by Table 21.
For other attributes recognized by the implementation, the value isimplementation-defined.
[Note 2:
It is expected that the availability of an attribute can be detected by any non-zero result.
— _end note_]
Table 21 — __has_cpp_attribute values [tab:cpp.cond.ha]
🔗Attribute | Value |
---|---|
🔗assume | 202207L |
🔗deprecated | 201309L |
🔗fallthrough | 201603L |
🔗likely | 201803L |
🔗maybe_unused | 201603L |
🔗no_unique_address | 201803L |
🔗nodiscard | 201907L |
🔗noreturn | 200809L |
🔗unlikely | 201803L |
The#ifdef, #ifndef, #elifdef, and #elifndefdirectives, and the defined conditional inclusion operator, shall treat __has_include, __has_embed, and __has_cpp_attributeas if they were the names of defined macros.
The identifiers __has_include, __has_embed, and __has_cpp_attributeshall not appear in any context not mentioned in this subclause.
Each preprocessing token that remains (in the list of preprocessing tokens that will become the controlling expression) after all macro replacements have occurred shall be in the lexical form of a token.
Preprocessing directives of the forms
check whether the controlling constant expression evaluates to nonzero.
Prior to evaluation, macro invocations in the list of preprocessing tokens that will become the controlling constant expression are replaced (except for those macro names modified by thedefinedunary operator), just as in normal text.
If the preprocessing tokendefinedis generated as a result of this replacement process or use of thedefinedunary operator does not match one of the two specified forms prior to macro replacement, the behavior is undefined.
After all replacements due to macro expansion and evaluations ofdefined-macro-expressions,has-include-expressions,has-embed-expressions, andhas-attribute-expression_s_have been performed, all remaining identifiers and keywords, except fortrueandfalse, are replaced with the pp-number 0, and then each preprocessing token is converted into a token.
[Note 3:
An alternative token is not an identifier, even when its spelling consists entirely of letters and underscores.
Therefore it is not subject to this replacement.
— _end note_]
The resulting tokens comprise the controlling constant expression which is evaluated according to the rules of [expr.const]using arithmetic that has at least the ranges specified in [support.limits].
For the purposes of this token conversion and evaluation all signed and unsigned integer types act as if they have the same representation as, respectively,intmax_t or uintmax_t ([cstdint.syn]).
[Note 4:
Thus on an implementation where std::numeric_limits<int>::max() is 0x7FFFand std::numeric_limits<unsigned int>::max() is 0xFFFF, the integer literal 0x8000 is signed and positive within a #ifexpression even though it is unsigned in translation phase 7.
— _end note_]
[Note 5:
The associated character encodings of literals are the same in #if and #elif directives and in any expression.
— _end note_]
Each subexpression with typeboolis subjected to integral promotion before processing continues.
Preprocessing directives of the forms
check whether the identifier is or is not currently defined as a macro name.
Each directive's condition is checked in order.
If it evaluates to false (zero), the group that it controls is skipped: directives are processed only through the name that determines the directive in order to keep track of the level of nested conditionals; the rest of the directives' preprocessing tokens are ignored, as are the other preprocessing tokens in the group.
Only the first group whose control condition evaluates to true (nonzero) is processed; any following groups are skipped and their controlling directives are processed as if they were in a group that is skipped.
If none of the conditions evaluates to true, and there is a#else directive, the group controlled by the#elseis processed; lacking a#elsedirective, all the groups until the#endif are skipped.124
[Example 1:
This demonstrates a way to include a library optional facility only if it is available:#if __has_include(<optional>) # include <optional> # if __cpp_lib_optional >= 201603 # define have_optional 1 # endif #elif __has_include(<experimental/optional>) # include <experimental/optional> # if __cpp_lib_experimental_optional >= 201411 # define have_optional 1 # define experimental_optional 1 # endif #endif #ifndef have_optional# define have_optional 0 #endif
— _end example_]
[Example 2:
This demonstrates a way to use the attribute [[acme::deprecated]]only if it is available.
#if __has_cpp_attribute(acme::deprecated) # define ATTR_DEPRECATED(msg) [[acme::deprecated(msg)]] #else # define ATTR_DEPRECATED(msg) [[deprecated(msg)]] #endifATTR_DEPRECATED("This function is deprecated") void anvil(); — _end example_]
15.3 Source file inclusion [cpp.include]
A#includedirective shall identify a header or source file that can be processed by the implementation.
A preprocessing directive of the form
searches a sequence ofimplementation-defined places for a header identified uniquely by the specified sequence between the<and>delimiters, and causes the replacement of that directive by the entire contents of the header.
How the places are specified or the header identified is implementation-defined.
A preprocessing directive of the form
causes the replacement of that directive by the entire contents of the source file identified by the specified sequence between the"delimiters.
The named source file is searched for in animplementation-defined manner.
If this search is not supported, or if the search fails, the directive is reprocessed as if it read
with the identical contained sequence (including>characters, if any) from the original directive.
A preprocessing directive of the form
(that does not match one of the two previous forms) is permitted.
The preprocessing tokens afterincludein the directive are processed just as in normal text (i.e., each identifier currently defined as a macro name is replaced by its replacement list of preprocessing tokens).
If the directive resulting after all replacements does not match one of the two previous forms, the behavior is undefined.
The method by which a sequence of preprocessing tokens between a<and a>preprocessing token pair or a pair of"characters is combined into a single header name preprocessing token is implementation-defined.
The implementation shall provide unique mappings for sequences consisting of one or morenondigits or digits ([lex.name]) followed by a period (.) and a singlenondigit.
The first character shall not be a digit.
The implementation may ignore distinctions of alphabetical case.
A#includepreprocessing directive may appear in a source file that has been read because of a#includedirective in another file, up to an implementation-defined nesting limit.
If the header identified by the denotes an importable header ([module.import]), it isimplementation-defined whether the #include preprocessing directive is instead replaced by an import directive ([cpp.import]) of the form
[Note 2:
An implementation can provide a mechanism for making arbitrary source files available to the < > search.
However, using the < > form for headers provided with the implementation and the " " form for sources outside the control of the implementation achieves wider portability.
For instance:#include <stdio.h> #include <unistd.h> #include "usefullib.h" #include "myprog.h"
— _end note_]
[Example 1:
This illustrates macro-replaced#includedirectives:#if VERSION == 1 #define INCFILE "vers1.h" #elif VERSION == 2 #define INCFILE "vers2.h" #else #define INCFILE "versN.h" #endif #include INCFILE
— _end example_]
15.4 Resource inclusion [cpp.embed]
15.4.1 General [cpp.embed.gen]
A preprocessing directive of the form
searches a sequence ofimplementation-defined places for a resource identified uniquely by the specified sequence between the < and > delimiters.
How the places are specified or the resource identified isimplementation-defined.
A preprocessing directive of the form
searches for a resource identified by the specified sequence between the" delimiters.
The named resource is searched for in animplementation-defined manner.
If this search is not supported, or if the search fails, the directive is reprocessed as if it read
with the identical contained sequence (including > characters, if any) from the original directive.
Recommended practice: A mechanism similar to, but distinct from, theimplementation-defined search paths used for #include ([cpp.include]) is encouraged.
Either form of the #embed directive processes thepp-tokens, if present, just as in normal text.
The pp-tokens shall then have the formembed-parameter-seq.
A resource is a source of data accessible from the translation environment.
A resource has an implementation-resource-width, which is theimplementation-defined size in bits of the resource.
If the implementation-resource-width is not an integral multiple ofCHAR_BIT, the program is ill-formed.
Let implementation-resource-count be implementation-resource-width divided by CHAR_BIT.
Every resource also has a resource-count, which is
- the value as computed from the optionally-provided limit embed-parameter ([cpp.embed.param.limit]), if present;
- otherwise, the implementation-resource-count.
A resource is empty if the resource-count is zero.
[Example 1: #embed "6_bits.bin" — _end example_]
The #embed directive is replaced by a comma-delimited list of integer literals of type int, unless otherwise modified by embed parameters ([cpp.embed.param]).
The integer literals in the comma-delimited list correspond to resource-count consecutive calls to std::fgetc ([cstdio.syn]) from the resource, as a binary file.
If any call to std::fgetc returns EOF, the program is ill-formed.
Recommended practice: The value of each integer literal should closely represent the bit stream of the resource unmodified.
This can require an implementation to consider potential differences between translation and execution environments, as well as any other applicable sources of mismatch.
[Example 2: #include <cstring> #include <cstddef> #include <fstream> #include <vector> #include <cassert> int main() { constexpr unsigned char d[] = { #embed <data.dat> };const std::vector<unsigned char> vec_d = { #embed <data.dat> };constexpr std::size_t expected_size = sizeof(d); std::ifstream f_source("data.dat", std::ios::binary | std::ios::in);unsigned char runtime_d[expected_size];char* ifstream_ptr = reinterpret_cast<char*>(runtime_d); assert(!f_source.read(ifstream_ptr, expected_size)); std::size_t ifstream_size = f_source.gcount(); assert (ifstream_size == expected_size);int is_same = std::memcmp(&d[0], ifstream_ptr, ifstream_size); assert(is_same == 0);int is_same_vec = std::memcmp(vec_d.data(), ifstream_ptr, ifstream_size); assert(is_same_vec == 0);} — _end example_]
[Example 3: int i = { #embed "i.dat" }; int i2 = #embed "i.dat"; struct s { double a, b, c;struct { double e, f, g; } x;double h, i, j;}; s x = { #embed "s.dat" }; — _end example_]
A preprocessing directive of the form
(that does not match one of the two previous forms) is permitted.
The preprocessing tokens after embed in the directive are processed just as in normal text (i.e., each identifier currently defined as a macro name is replaced by its replacement list of preprocessing tokens).
The directive resulting after all replacements of the third form shall match one of the two previous forms.
Any further processing as in normal text described for the two previous forms is not performed.
[Note 2:
That is, processing as in normal text happens once and only once for the entire directive.
— _end note_]
[Example 4:
If the directive matches the third form, the whole directive is replaced.
If the directive matches the first two forms, everything after the name is replaced.
#define prefix(ARG) suffix(ARG) #define THE_ADDITION "teehee" #define THE_RESOURCE ":3c" #embed ":3c" prefix(THE_ADDITION) #embed THE_RESOURCE prefix(THE_ADDITION)
#embed ":3c" suffix("teehee") #embed ":3c" suffix("teehee") — _end example_]
The method by which a sequence of preprocessing tokens between a < and a > preprocessing token pair or a pair of " characters is combined into a single resource name preprocessing token isimplementation-defined.
15.4.2 Embed parameters [cpp.embed.param]
15.4.2.1 limit parameter [cpp.embed.param.limit]
An embed-parameter of the formlimit ( pp-balanced-token-seq )specifies the maximum possible number of elements in the comma-delimited list.
It shall appear at most once in the embed-parameter-seq.
The pp-balanced-token-seq is evaluated as aconstant-expression using the rules as described in conditional inclusion ([cpp.cond]), but without being processed as in normal text an additional time.
[Example 1: #undef DATA_LIMIT#if __has_embed(<data.dat> limit(DATA_LIMIT)) #endif
#if __has_embed(<data.dat> limit(0)) #endif — _end example_]
[Example 2: #embed <data.dat> limit(__has_include("a.h")) #if __has_embed(<data.dat> limit(__has_include("a.h"))) #endif — _end example_]
The constant-expression shall be an integral constant expression whose value is greater than or equal to zero.
The resource-count ([cpp.embed.gen]) becomes implementation-resource-count, if the value of theconstant-expression is greater than implementation-resource-count; otherwise, the value of theconstant-expression.
[Example 3: constexpr unsigned char sound_signature[] = { #embed <sdk/jump.wav> limit(2+2) };static_assert(sizeof(sound_signature) == 4); — _end example_]
15.4.2.2 prefix parameter [cpp.embed.param.prefix]
An embed-parameter of the form
prefix ( pp-balanced-token-seq )
shall appear at most once in the embed-parameter-seq.
If the resource is empty, this embed-parameter is ignored.
Otherwise, the pp-balanced-token-seq is placed immediately before the comma-delimited list of integral literals.
15.4.2.3 suffix parameter [cpp.embed.param.suffix]
An embed-parameter of the form
suffix ( pp-balanced-token-seq )
shall appear at most once in the embed-parameter-seq.
If the resource is empty, this embed-parameter is ignored.
Otherwise, the pp-balanced-token-seq is placed immediately after the comma-delimited list of the integral constant expressions.
[Example 1: constexpr unsigned char whl[] = { #embed "ches.glsl" \ prefix(0xEF, 0xBB, 0xBF, ) \ suffix(,) 0 };constexpr bool is_empty = sizeof(whl) == 1 && whl[0] == '\0';constexpr bool is_not_empty = sizeof(whl) >= 4 && whl[sizeof(whl) - 1] == '\0' && whl[0] == '\xEF' && whl[1] == '\xBB' && whl[2] == '\xBF';static_assert(is_empty || is_not_empty); — _end example_]
15.4.2.4 if_empty parameter [cpp.embed.param.if.empty]
An embed-parameter of the form
if_empty ( pp-balanced-token-seq )
shall appear at most once in the embed-parameter-seq.
If the resource is not empty, this embed-parameter is ignored.
Otherwise, the #embed directive is replaced by thepp-balanced-token-seq.
[Example 1:
limit(0) affects when a resource is considered empty.
Therefore, the following program:
#embed </owo/uwurandom> \ if_empty(42203) limit(0) expands to42203
— _end example_]
[Example 2:
This resource is considered empty due to the limit(0) embed-parameter, always, including in __has_embed clauses.
int infinity_zero () { #if __has_embed(</owo/uwurandom> limit(0) prefix(some tokens)) == __STDC_EMBED_EMPTY__return 0;#else #error "The resource does not exist" #endif } — _end example_]
15.5 Module directive [cpp.module]
pp-module:
export module pp-tokens ; new-line
A pp-module shall not appear in a context where moduleor (if it is the first preprocessing token of the pp-module) exportis an identifier defined as an object-like macro.
The pp-tokens, if any, of a pp-moduleshall be of the form:
where the pp-tokens (if any) shall not begin with a ( preprocessing token and the grammar non-terminals are defined as:
No identifier in the pp-module-name or pp-module-partitionshall currently be defined as an object-like macro.
Any preprocessing tokens after the module preprocessing token in the module directive are processed just as in normal text.
[Note 1:
Each identifier currently defined as a macro name is replaced by its replacement list of preprocessing tokens.
— _end note_]
The module and export (if it exists) preprocessing tokens are replaced by the module-keyword and_export-keyword_ preprocessing tokens respectively.
[Note 2:
This makes the line no longer a directive so it is not removed at the end of phase 4.
— _end note_]
15.6 Header unit importation [cpp.import]
pp-import:
export import pp-tokens ; new-line
export import pp-tokens ; new-line
export import pp-tokens ; new-line
A pp-import shall not appear in a context where importor (if it is the first preprocessing token of the pp-import) exportis an identifier defined as an object-like macro.
The preprocessing tokens after the import preprocessing token in the import control-lineare processed just as in normal text (i.e., each identifier currently defined as a macro name is replaced by its replacement list of preprocessing tokens).
[Note 1:
An import directive matching the first two forms of a pp-importinstructs the preprocessor to import macros from the header unit ([module.import]) denoted by the , as described below.
— _end note_]
The point of macro import for the first two forms of pp-import is immediately after the new-line terminating the pp-import.
The last form of pp-import is only considered if the first two forms did not match, and does not have a point of macro import.
If a pp-import is produced by source file inclusion (including by the rewrite produced when a #include directive names an importable header) while processing the group of a module-file, the program is ill-formed.
In all three forms of pp-import, the import and export (if it exists) preprocessing tokens are replaced by the import-keyword and_export-keyword_ preprocessing tokens respectively.
[Note 2:
This makes the line no longer a directive so it is not removed at the end of phase 4.
— _end note_]
Additionally, in the second form of pp-import, a token is formed as if the were the pp-tokens of a #include directive.
The are replaced by the token.
[Note 3:
This ensures that imports are treated consistently by the preprocessor and later phases of translation.
— _end note_]
Each #define directive encountered when preprocessing each translation unit in a program results in a distinctmacro definition.
[Note 4:
A predefined macro name ([cpp.predefined]) is not introduced by a #define directive.
Implementations providing mechanisms to predefine additional macros are encouraged to not treat them as being introduced by a #define directive.
— _end note_]
Each macro definition has at most one point of definition in each translation unit and at most one point of undefinition, as follows:
- The point of definitionof a macro definition within a translation unit T is
- if the #define directive of the macro definition occurs within T, the point at which that directive occurs, or otherwise,
- if the macro name is not lexically identical to a keyword ([lex.key]) or to the identifiers module or import, the first point of macro import in T of a header unit containing a point of definition for the macro definition, if any.
In the latter case, the macro is said to be imported from the header unit.
- The point of undefinitionof a macro definition within a translation unit is the first point at which a #undef directive naming the macro occurs after its point of definition, or the first point of macro import of a header unit containing a point of undefinition for the macro definition, whichever (if any) occurs first.
A macro definition is active at a source location if it has a point of definition in that translation unit preceding the location, and does not have a point of undefinition in that translation unit preceding the location.
If a macro would be replaced or redefined, and multiple macro definitions are active for that macro name, the active macro definitions shall all be valid redefinitions of the same macro ([cpp.replace]).
[Note 5:
The relative order of pp-imports has no bearing on whether a particular macro definition is active.
— _end note_]
[Example 1:
Importable header "a.h":#define X 123 #define Y 45 #define Z a #undef X
Importable header "b.h":import "a.h"; #define X 456 #define Y 6
Importable header "c.h":#define Y 45 #define Z c
Importable header "d.h":import "c.h";
Importable header "e.h":import "a.h"; import "d.h"; int a = Y; int c = Z;
Module unit f:export module f;export import "a.h";int a = Y;
Translation unit #1:import f;int x = Y; — _end example_]
15.7 Macro replacement [cpp.replace]
15.7.1 General [cpp.replace.general]
Two replacement lists are identical if and only if the preprocessing tokens in both have the same number, ordering, spelling, and whitespace separation, where all whitespace separations are considered identical.
An identifier currently defined as anobject-like macro (see below) may be redefined by another#definepreprocessing directive provided that the second definition is an object-like macro definition and the two replacement lists are identical, otherwise the program is ill-formed.
Likewise, an identifier currently defined as afunction-like macro (see below) may be redefined by another#definepreprocessing directive provided that the second definition is a function-like macro definition that has the same number and spelling of parameters, and the two replacement lists are identical, otherwise the program is ill-formed.
[Example 1:
The following sequence is valid:#define OBJ_LIKE (1-1) #define OBJ_LIKE (1-1) #define FUNC_LIKE(a) ( a ) #define FUNC_LIKE( a )( \ a )
But the following redefinitions are invalid:#define OBJ_LIKE (0) #define OBJ_LIKE (1 - 1) #define FUNC_LIKE(b) ( a ) #define FUNC_LIKE(b) ( b )
— _end example_]
There shall be whitespace between the identifier and the replacement list in the definition of an object-like macro.
If the identifier-list in the macro definition does not end with an ellipsis, the number of arguments (including those arguments consisting of no preprocessing tokens) in an invocation of a function-like macro shall equal the number of parameters in the macro definition.
Otherwise, there shall be at least as many arguments in the invocation as there are parameters in the macro definition (excluding the ...).
There shall exist a)preprocessing token that terminates the invocation.
The identifiers __VA_ARGS__ and __VA_OPT__shall occur only in the replacement-listof a function-like macro that uses the ellipsis notation in the parameters.
A parameter identifier in a function-like macro shall be uniquely declared within its scope.
The identifier immediately following thedefineis called themacro name.
There is one name space for macro names.
Any whitespace characters preceding or following the replacement list of preprocessing tokens are not considered part of the replacement list for either form of macro.
If a #preprocessing token, followed by an identifier, occurs lexically at the point at which a preprocessing directive can begin, the identifier is not subject to macro replacement.
A preprocessing directive of the form
defines anobject-like macro that causes each subsequent instance of the macro name125to be replaced by the replacement list of preprocessing tokens that constitute the remainder of the directive.126
The replacement list is then rescanned for more macro names as specified below.
[Example 2:
The simplest use of this facility is to define a “manifest constant”, as in#define TABSIZE 100 int table[TABSIZE];
— _end example_]
A preprocessing directive of the form
defines a function-like macrowith parameters, whose use is similar syntactically to a function call.
The parametersare specified by the optional list of identifiers.
Each subsequent instance of the function-like macro name followed by a(as the next preprocessing token introduces the sequence of preprocessing tokens that is replaced by the replacement list in the definition (an invocation of the macro).
The replaced sequence of preprocessing tokens is terminated by the matching)preprocessing token, skipping intervening matched pairs of left and right parenthesis preprocessing tokens.
Within the sequence of preprocessing tokens making up an invocation of a function-like macro, new-line is considered a normal whitespace character.
The sequence of preprocessing tokens bounded by the outside-most matching parentheses forms the list of arguments for the function-like macro.
The individual arguments within the list are separated by comma preprocessing tokens, but comma preprocessing tokens between matching inner parentheses do not separate arguments.
If there are sequences of preprocessing tokens within the list of arguments that would otherwise act as preprocessing directives,127the behavior is undefined.
[Example 3:
The following defines a function-like macro whose value is the maximum of its arguments.
It has the disadvantages of evaluating one or the other of its arguments a second time (includingside effects) and generating more code than a function if invoked several times.
It also cannot have its address taken, as it has none.
#define max(a, b) ((a) > (b) ? (a) : (b))
The parentheses ensure that the arguments and the resulting expression are bound properly.
— _end example_]
If there is a ... immediately preceding the ) in the function-like macro definition, then the trailing arguments (if any), including any separating comma preprocessing tokens, are merged to form a single item: the variable arguments.
The number of arguments so combined is such that, following merger, the number of arguments is either equal to or one more than the number of parameters in the macro definition (excluding the...).
15.7.2 Argument substitution [cpp.subst]
va-opt-replacement:
__VA_OPT__ ( pp-tokens )
After the arguments for the invocation of a function-like macro have been identified, argument substitution takes place.
For each parameter in the replacement list that is neither preceded by a # or ## preprocessing token nor followed by a ## preprocessing token, the preprocessing tokens naming the parameter are replaced by a preprocessing token sequence determined as follows:
- If the parameter is of the form va-opt-replacement, the replacement preprocessing tokens are the preprocessing token sequence for the corresponding argument, as specified below.
- Otherwise, the replacement preprocessing tokens are the preprocessing tokens of corresponding argument after all macros contained therein have been expanded.
The argument's preprocessing tokens are completely macro replaced before being substituted as if they formed the rest of the preprocessing translation unit with no other preprocessing tokens being available.
[Example 1: #define LPAREN() ( #define G(Q) 42 #define F(R, X, ...) __VA_OPT__(G R X) ) int x = F(LPAREN(), 0, <:-); — _end example_]
An identifier __VA_ARGS__ that occurs in the replacement list shall be treated as if it were a parameter, and the variable arguments shall form the preprocessing tokens used to replace it.
[Example 2:
#define debug(...) fprintf(stderr, __VA_ARGS__) #define showlist(...) puts(#__VA_ARGS__) #define report(test, ...) ((test) ? puts(#test) : printf(__VA_ARGS__))debug("Flag"); debug("X = %d\n", x); showlist(The first, second, and third items.); report(x>y, "x is %d but y is %d", x, y);results infprintf(stderr, "Flag"); fprintf(stderr, "X = %d\n", x); puts("The first, second, and third items.");((x>y) ? puts("x>y") : printf("x is %d but y is %d", x, y));
— _end example_]
The identifier __VA_OPT__shall always occur as part of the preprocessing token sequenceva-opt-replacement; its closing ) is determined by skipping intervening pairs of matching left and right parentheses in its pp-tokens.
The pp-tokens of a va-opt-replacementshall not contain __VA_OPT__.
If the pp-tokens would be ill-formed as the replacement list of the current function-like macro, the program is ill-formed.
A va-opt-replacement is treated as if it were a parameter, and the preprocessing token sequence for the corresponding argument is defined as follows.
If the substitution of __VA_ARGS__ as neither an operand of # nor ## consists of no preprocessing tokens, the argument consists of a single placemarker preprocessing token ([cpp.concat], [cpp.rescan]).
Otherwise, the argument consists of the results of the expansion of the contained pp-tokensas the replacement list of the current function-like macro before removal of placemarker tokens, rescanning, and further replacement.
[Note 1:
The placemarker tokens are removed before stringization ([cpp.stringize]), and can be removed by rescanning and further replacement ([cpp.rescan]).
— _end note_]
[Example 3: #define F(...) f(0 __VA_OPT__(,) __VA_ARGS__) #define G(X, ...) f(0, X __VA_OPT__(,) __VA_ARGS__) #define SDEF(sname, ...) S sname __VA_OPT__(= { __VA_ARGS__ }) #define EMP F(a, b, c)F()F(EMP)G(a, b, c)G(a, )G(a)SDEF(foo); SDEF(bar, 1, 2); #define H1(X, ...) X __VA_OPT__(##) __VA_ARGS__ #define H2(X, Y, ...) __VA_OPT__(X ## Y,) __VA_ARGS__ H2(a, b, c, d) #define H3(X, ...) #__VA_OPT__(X##X X##X)H3(, 0) #define H4(X, ...) __VA_OPT__(a X ## X) ## b H4(, 1) #define H5A(...) __VA_OPT__()__VA_OPT__() #define H5B(X) a ## X ## b#define H5C(X) H5B(X)H5C(H5A()) — _end example_]
15.7.3 The # operator [cpp.stringize]
Each#preprocessing token in the replacement list for a function-like macro shall be followed by a parameter as the next preprocessing token in the replacement list.
If, in the replacement list, a parameter is immediately preceded by a#preprocessing token, both are replaced by a single character string literal preprocessing token that contains the spelling of the preprocessing token sequence for the corresponding argument (excluding placemarker tokens).
Let the stringizing argument be the preprocessing token sequence for the corresponding argument with placemarker tokens removed.
Each occurrence of whitespace between the stringizing argument's preprocessing tokens becomes a single space character in the character string literal.
Whitespace before the first preprocessing token and after the last preprocessing token comprising the stringizing argument is deleted.
Otherwise, the original spelling of each preprocessing token in the stringizing argument is retained in the character string literal, except for special handling for producing the spelling ofstring-literals and character-literals: a\character is inserted before each"and\character of a character-literal or string-literal(including the delimiting"characters).
If the replacement that results is not a valid character string literal, the behavior is undefined.
The character string literal corresponding to an empty stringizing argument is "".
The order of evaluation of#and##operators is unspecified.
15.7.4 The ## operator [cpp.concat]
A##preprocessing token shall not occur at the beginning or at the end of a replacement list for either form of macro definition.
If, in the replacement list of a function-like macro, a parameter is immediately preceded or followed by a##preprocessing token, the parameter is replaced by the corresponding argument's preprocessing token sequence; however, if an argument consists of no preprocessing tokens, the parameter is replaced by a placemarker preprocessing token instead.128
For both object-like and function-like macro invocations, before the replacement list is reexamined for more macro names to replace, each instance of a##preprocessing token in the replacement list (not from an argument) is deleted and the preceding preprocessing token is concatenated with the following preprocessing token.
Placemarker preprocessing tokens are handled specially: concatenation of two placemarkers results in a single placemarker preprocessing token, and concatenation of a placemarker with a non-placemarker preprocessing token results in the non-placemarker preprocessing token.
If the result is not a valid preprocessing token, the behavior is undefined.
The resulting preprocessing token is available for further macro replacement.
The order of evaluation of##operators is unspecified.
[Example 1:
The sequence#define str(s) # s#define xstr(s) str(s) #define debug(s, t) printf("x" # s "= %d, x" # t "= %s", \ x ## s, x ## t) #define INCFILE(n) vers ## n#define glue(a, b) a ## b#define xglue(a, b) glue(a, b) #define HIGHLOW "hello" #define LOW LOW ", world"debug(1, 2); fputs(str(strncmp("abc\0d", "abc", '\4') == 0) str(: @\n), s);#include xstr(INCFILE(2).h)glue(HIGH, LOW); xglue(HIGH, LOW) results inprintf("x" "1" "= %d, x" "2" "= %s", x1, x2); fputs("strncmp(\"abc\\0d\", \"abc\", '\\4') == 0" ": @\n", s);#include "vers2.h" (after macro replacement, before file access) "hello";"hello" ", world" or, after concatenation of the character string literals,printf("x1= %d, x2= %s", x1, x2); fputs("strncmp(\"abc\\0d\", \"abc\", '\\4') == 0: @\n", s);#include "vers2.h" (after macro replacement, before file access) "hello";"hello, world"
Space around the # and ## preprocessing tokens in the macro definition is optional.
— _end example_]
[Example 2:
In the following fragment:#define hash_hash # ## # #define mkstr(a) # a#define in_between(a) mkstr(a) #define join(c, d) in_between(c hash_hash d) char p[] = join(x, y);
The expansion produces, at various stages:join(x, y)in_between(x hash_hash y)in_between(x ## y)mkstr(x ## y) "x ## y"
In other words, expanding hash_hash produces a new preprocessing token, consisting of two adjacent sharp signs, but this new preprocessing token is not the## operator.
— _end example_]
[Example 3:
To illustrate the rules for placemarker preprocessing tokens, the sequence#define t(x,y,z) x ## y ## zint j[] = { t(1,2,3), t(,4,5), t(6,,7), t(8,9,), t(10,,), t(,11,), t(,,12), t(,,) };results inint j[] = { 123, 45, 67, 89,10, 11, 12, };
— _end example_]
15.7.5 Rescanning and further replacement [cpp.rescan]
After all parameters in the replacement list have been substituted and # and ## processing has taken place, all placemarker preprocessing tokens are removed.
Then the resulting preprocessing token sequence is rescanned, along with all subsequent preprocessing tokens of the source file, for more macro names to replace.
[Example 1:
The sequence#define x 3 #define f(a) f(x * (a)) #undef x#define x 2 #define g f#define z z[0] #define h g(~ #define m(a) a(w) #define w 0,1 #define t(a) a#define p() int #define q(x) x#define r(x,y) x ## y#define str(x) # x f(y+1) + f(f(z)) % t(t(g)(0) + t)(1); g(x+(3,4)-w) | h 5) & m(f)^m(m); p() i[q()] = { q(1), r(2,3), r(4,), r(,5), r(,) };char c[2][6] = { str(hello), str() };results inf(2 * (y+1)) + f(2 * (f(2 * (z[0])))) % f(2 * (0)) + t(1); f(2 * (2+(3,4)-0,1)) | f(2 * (~ 5)) & f(2 * (0,1))^m(0,1);int i[] = { 1, 23, 4, 5, };char c[2][6] = { "hello", "" };
— _end example_]
If the name of the macro being replaced is found during this scan of the replacement list (not including the rest of the source file's preprocessing tokens), it is not replaced.
Furthermore, if any nested replacements encounter the name of the macro being replaced, it is not replaced.
These nonreplaced macro name preprocessing tokens are no longer available for further replacement even if they are later (re)examined in contexts in which that macro name preprocessing token would otherwise have been replaced.
The resulting completely macro-replaced preprocessing token sequence is not processed as a preprocessing directive even if it resembles one, but all pragma unary operator expressions within it are then processed as specified in [cpp.pragma.op] below.
15.7.6 Scope of macro definitions [cpp.scope]
A macro definition lasts (independent of block structure) until a corresponding#undefdirective is encountered or (if none is encountered) until the end of the translation unit.
Macro definitions have no significance after translation phase 4.
A preprocessing directive of the form
causes the specified identifier no longer to be defined as a macro name.
It is ignored if the specified identifier is not currently defined as a macro name.
15.8 Line control [cpp.line]
The string-literal of a#linedirective, if present, shall be a character string literal.
Theline numberof the current source line is the line number of the current physical source line, i.e., it is one greater than the number of new-line characters read or introduced in translation phase 1while processing the source file to the current preprocessing token.
A preprocessing directive of the form
causes the implementation to behave as if the following sequence of source lines begins with a source line that has a line number as specified by the digit sequence (interpreted as a decimal integer).
If the digit sequence specifies zero or a number greater than 2147483647, the behavior is undefined.
A preprocessing directive of the form
sets the presumed line number similarly and changes the presumed name of the source file to be the contents of the character string literal.
A preprocessing directive of the form
(that does not match one of the two previous forms) is permitted.
The preprocessing tokens afterlineon the directive are processed just as in normal text (each identifier currently defined as a macro name is replaced by its replacement list of preprocessing tokens).
If the directive resulting after all replacements does not match one of the two previous forms, the behavior is undefined; otherwise, the result is processed as appropriate.
15.9 Diagnostic directives [cpp.error]
A preprocessing directive of the form
renders the program ill-formed.
A preprocessing directive of the form
requires the implementation to produce at least one diagnostic message for the preprocessing translation unit ([intro.compliance.general]).
Recommended practice: Any diagnostic message caused by either of these directives should include the specified sequence of preprocessing tokens.
15.10 Pragma directive [cpp.pragma]
A preprocessing directive of the form
causes the implementation to behave in an implementation-defined manner.
The behavior may cause translation to fail or cause the translator or the resulting program to behave in a non-conforming manner.
Any pragma that is not recognized by the implementation is ignored.
15.11 Null directive [cpp.null]
A preprocessing directive of the form
new-line
has no effect.
15.12 Predefined macro names [cpp.predefined]
The following macro names shall be defined by the implementation:
- __cplusplus
The integer literal 202302L.
[Note 1:
Future revisions of this document will replace the value of this macro with a greater value.
— _end note_] - The names listed in Table 22.
The macros defined in Table 22 shall be defined to the corresponding integer literal.
[Note 2:
Future revisions of this document might replace the values of these macros with greater values.
— _end note_] - __DATE__
The date of translation of the source file: a character string literal of the form"Mmm dd yyyy", where the names of the months are the same as those generated by theasctimefunction, and the first character ofddis a space character if the value is less than 10.
If the date of translation is not available, an implementation-defined valid date shall be supplied. - __FILE__
The presumed name of the current source file (a character string literal).129 - __LINE__
The presumed line number (within the current source file) of the current source line (an integer literal).130 - __STDC_EMBED_NOT_FOUND__, __STDC_EMBED_FOUND__, and __STDC_EMBED_EMPTY__
The integer literals 0, 1, and 2, respectively.
[Note 3:
These represent values replaced from has-embed-expressions ([cpp.cond]).
— _end note_] - __STDC_HOSTED__
The integer literal 1if the implementation is a hosted implementation or the integer literal 0if it is a freestanding implementation ([intro.compliance]). - __STDCPP_DEFAULT_NEW_ALIGNMENT__
An integer literal of type std::size_twhose value is the alignment guaranteed by a call to operator new(std::size_t)or operator new[](std::size_t).
[Note 4:
Larger alignments will be passed tooperator new(std::size_t, std::align_val_t), etc.
— _end note_] - __STDCPP_FLOAT16_T__
Defined as the integer literal 1if and only if the implementation supports the ISO/IEC 60559 floating-point interchange format binary16 as an extended floating-point type ([basic.extended.fp]). - __STDCPP_FLOAT32_T__
Defined as the integer literal 1if and only if the implementation supports the ISO/IEC 60559 floating-point interchange format binary32 as an extended floating-point type. - __STDCPP_FLOAT64_T__
Defined as the integer literal 1if and only if the implementation supports the ISO/IEC 60559 floating-point interchange format binary64 as an extended floating-point type. - __STDCPP_FLOAT128_T__
Defined as the integer literal 1if and only if the implementation supports the ISO/IEC 60559 floating-point interchange format binary128 as an extended floating-point type. - __STDCPP_BFLOAT16_T__
Defined as the integer literal 1if and only if the implementation supports an extended floating-point type with the properties of the typedef-name std::bfloat16_tas described in [basic.extended.fp]. - __TIME__
The time of translation of the source file: a character string literal of the form"hh:mm:ss"as in the time generated by theasctimefunction.
If the time of translation is not available, an implementation-defined valid time shall be supplied.
Table 22 — Feature-test macros [tab:cpp.predefined.ft]
🔗Macro name | Value |
---|---|
🔗__cpp_aggregate_bases | 201603L |
🔗__cpp_aggregate_nsdmi | 201304L |
🔗__cpp_aggregate_paren_init | 201902L |
🔗__cpp_alias_templates | 200704L |
🔗__cpp_aligned_new | 201606L |
🔗__cpp_attributes | 200809L |
🔗__cpp_auto_cast | 202110L |
🔗__cpp_binary_literals | 201304L |
🔗__cpp_capture_star_this | 201603L |
🔗__cpp_char8_t | 202207L |
🔗__cpp_concepts | 202002L |
🔗__cpp_conditional_explicit | 201806L |
🔗__cpp_constexpr | 202406L |
🔗__cpp_constexpr_dynamic_alloc | 201907L |
🔗__cpp_constexpr_exceptions | 202411L |
🔗__cpp_constexpr_in_decltype | 201711L |
🔗__cpp_consteval | 202211L |
🔗__cpp_constinit | 201907L |
🔗__cpp_contracts | 202502L |
🔗__cpp_decltype | 200707L |
🔗__cpp_decltype_auto | 201304L |
🔗__cpp_deduction_guides | 201907L |
🔗__cpp_delegating_constructors | 200604L |
🔗__cpp_deleted_function | 202403L |
🔗__cpp_designated_initializers | 201707L |
🔗__cpp_enumerator_attributes | 201411L |
🔗__cpp_explicit_this_parameter | 202110L |
🔗__cpp_fold_expressions | 201603L |
🔗__cpp_generic_lambdas | 201707L |
🔗__cpp_guaranteed_copy_elision | 201606L |
🔗__cpp_hex_float | 201603L |
🔗__cpp_if_consteval | 202106L |
🔗__cpp_if_constexpr | 201606L |
🔗__cpp_impl_coroutine | 201902L |
🔗__cpp_impl_destroying_delete | 201806L |
🔗__cpp_impl_three_way_comparison | 201907L |
🔗__cpp_implicit_move | 202207L |
🔗__cpp_inheriting_constructors | 201511L |
🔗__cpp_init_captures | 201803L |
🔗__cpp_initializer_lists | 200806L |
🔗__cpp_inline_variables | 201606L |
🔗__cpp_lambdas | 200907L |
🔗__cpp_modules | 201907L |
🔗__cpp_multidimensional_subscript | 202211L |
🔗__cpp_named_character_escapes | 202207L |
🔗__cpp_namespace_attributes | 201411L |
🔗__cpp_noexcept_function_type | 201510L |
🔗__cpp_nontype_template_args | 201911L |
🔗__cpp_nontype_template_parameter_auto | 201606L |
🔗__cpp_nsdmi | 200809L |
🔗__cpp_pack_indexing | 202311L |
🔗__cpp_placeholder_variables | 202306L |
🔗__cpp_pp_embed | 202502L |
🔗__cpp_range_based_for | 202211L |
🔗__cpp_raw_strings | 200710L |
🔗__cpp_ref_qualifiers | 200710L |
🔗__cpp_return_type_deduction | 201304L |
🔗__cpp_rvalue_references | 200610L |
🔗__cpp_size_t_suffix | 202011L |
🔗__cpp_sized_deallocation | 201309L |
🔗__cpp_static_assert | 202306L |
🔗__cpp_static_call_operator | 202207L |
🔗__cpp_structured_bindings | 202411L |
🔗__cpp_template_parameters | 202502L |
🔗__cpp_template_template_args | 201611L |
🔗__cpp_threadsafe_static_init | 200806L |
🔗__cpp_trivial_relocatability | 202502L |
🔗__cpp_trivial_union | 202502L |
🔗__cpp_unicode_characters | 200704L |
🔗__cpp_unicode_literals | 200710L |
🔗__cpp_user_defined_literals | 200809L |
🔗__cpp_using_enum | 201907L |
🔗__cpp_variable_templates | 201304L |
🔗__cpp_variadic_friend | 202403L |
🔗__cpp_variadic_templates | 200704L |
🔗__cpp_variadic_using | 201611L |
The following macro names are conditionally defined by the implementation:
- __STDC__
Whether __STDC__ is predefined and if so, what its value is, are implementation-defined. - __STDC_MB_MIGHT_NEQ_WC__
The integer literal 1, intended to indicate that, in the encoding forwchar_t, a member of the basic character set need not have a code value equal to its value when used as the lone character in an ordinary character literal. - __STDC_VERSION__
Whether __STDC_VERSION__ is predefined and if so, what its value is, are implementation-defined. - __STDC_ISO_10646__
An integer literal of the form yyyymmL(for example, 199712L).
Whether __STDC_ISO_10646__ is predefined and if so, what its value is, are implementation-defined. - __STDCPP_THREADS__
Defined, and has the value integer literal 1, if and only if a program can have more than one thread of execution.
The values of the predefined macros (except for__FILE__and__LINE__) remain constant throughout the translation unit.
If any of the pre-defined macro names in this subclause, or the identifierdefined, is the subject of a#defineor a#undefpreprocessing directive, the behavior is undefined.
Any other predefined macro names shall begin with a leading underscore followed by an uppercase letter or a second underscore.
15.13 Pragma operator [cpp.pragma.op]
A unary operator expression of the form:
is processed as follows: The string-literal is destringizedby deleting the L prefix, if present, deleting the leading and trailing double-quotes, replacing each escape sequence \" by a double-quote, and replacing each escape sequence \\ by a single backslash.
The resulting sequence of characters is processed through translation phase 3 to produce preprocessing tokens that are executed as if they were thepp-tokens in a pragma directive.
The original four preprocessing tokens in the unary operator expression are removed.
[Example 1:
#pragma listing on "..\listing.dir" can also be expressed as:_Pragma ( "listing on \"..\\listing.dir\"" )
The latter form is processed in the same way whether it appears literally as shown, or results from macro replacement, as in:#define LISTING(x) PRAGMA(listing on #x) #define PRAGMA(x) _Pragma(#x)LISTING( ..\listing.dir )
— _end example_]