This commit is contained in:
2025-10-25 03:02:53 +03:00
commit 043225d523
3416 changed files with 681196 additions and 0 deletions

103
cppdraft/cpp/concat.md Normal file
View File

@@ -0,0 +1,103 @@
[cpp.concat]
# 15 Preprocessing directives [[cpp]](./#cpp)
## 15.7 Macro replacement [[cpp.replace]](cpp.replace#cpp.concat)
### 15.7.4 The ## operator [cpp.concat]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L1847)
A## preprocessing token shall not occur at the beginning or
at the end of a replacement list for either form
of macro definition[.](#1.sentence-1)
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L1854)
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[.](#2.sentence-1)[128](#footnote-128 "Placemarker preprocessing tokens do not appear in the syntax because they are temporary entities that exist only within translation phase 4.")
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L1866)
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[.](#3.sentence-1)
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[.](#3.sentence-2)
[*Note [1](#note-1)*:
Concatenation can form
a [*universal-character-name*](lex.universal.char#nt:universal-character-name "5.3.2Universal character names[lex.universal.char]") ([[lex.charset]](lex.charset "5.3.1Character sets"))[.](#3.sentence-3)
— *end note*]
If the result is not a valid preprocessing token,
the program is ill-formed[.](#3.sentence-4)
The resulting preprocessing token is available for further macro replacement[.](#3.sentence-5)
The order of evaluation of## operators is unspecified[.](#3.sentence-6)
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L1890)
[*Example [1](#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') // this goes away== 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[.](#4.sentence-2)
— *end example*]
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L1932)
[*Example [2](#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); // equivalent to char p[] = "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[.](#5.sentence-3)
— *end example*]
[6](#6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L1957)
[*Example [3](#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*]
[128)](#footnote-128)[128)](#footnoteref-128)
Placemarker preprocessing tokens do not appear in the syntax
because they are temporary entities that exist only within translation phase 4[.](#footnote-128.sentence-1)

327
cppdraft/cpp/cond.md Normal file
View File

@@ -0,0 +1,327 @@
[cpp.cond]
# 15 Preprocessing directives [[cpp]](./#cpp)
## 15.2 Conditional inclusion [cpp.cond]
[defined-macro-expression:](#nt:defined-macro-expression "15.2Conditional inclusion[cpp.cond]")
defined [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]")
defined ( [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]") )
[h-preprocessing-token:](#nt:h-preprocessing-token "15.2Conditional inclusion[cpp.cond]")
any [*preprocessing-token*](lex.pptoken#nt:preprocessing-token "5.5Preprocessing tokens[lex.pptoken]") other than >
[h-pp-tokens:](#nt:h-pp-tokens "15.2Conditional inclusion[cpp.cond]")
[*h-preprocessing-token*](#nt:h-preprocessing-token "15.2Conditional inclusion[cpp.cond]") [*h-pp-tokens*](#nt:h-pp-tokens "15.2Conditional inclusion[cpp.cond]")opt
[header-name-tokens:](#nt:header-name-tokens "15.2Conditional inclusion[cpp.cond]")
[*string-literal*](lex.string#nt:string-literal "5.13.5String literals[lex.string]")
< [*h-pp-tokens*](#nt:h-pp-tokens "15.2Conditional inclusion[cpp.cond]") >
[has-include-expression:](#nt:has-include-expression "15.2Conditional inclusion[cpp.cond]")
__has_include ( [*header-name*](lex.header#nt:header-name "5.6Header names[lex.header]") )
__has_include ( [*header-name-tokens*](#nt:header-name-tokens "15.2Conditional inclusion[cpp.cond]") )
[has-embed-expression:](#nt:has-embed-expression "15.2Conditional inclusion[cpp.cond]")
__has_embed ( [*header-name*](lex.header#nt:header-name "5.6Header names[lex.header]") [*pp-balanced-token-seq*](cpp.pre#nt:pp-balanced-token-seq "15.1Preamble[cpp.pre]")opt )
__has_embed ( [*header-name-tokens*](#nt:header-name-tokens "15.2Conditional inclusion[cpp.cond]") [*pp-balanced-token-seq*](cpp.pre#nt:pp-balanced-token-seq "15.1Preamble[cpp.pre]")opt )
[has-attribute-expression:](#nt:has-attribute-expression "15.2Conditional inclusion[cpp.cond]")
__has_cpp_attribute ( [*pp-tokens*](cpp.pre#nt:pp-tokens "15.1Preamble[cpp.pre]") )
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L380)
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 below[123](#footnote-123 "Because the controlling constant expression is evaluated during translation phase 4, all identifiers either are or are not macro names — there simply are no keywords, enumeration constants, etc.") and it may contain zero or more[*defined-macro-expression*](#nt:defined-macro-expression "15.2Conditional inclusion[cpp.cond]")*s*,[*has-include-expression*](#nt:has-include-expression "15.2Conditional inclusion[cpp.cond]")*s*,[*has-attribute-expression*](#nt:has-attribute-expression "15.2Conditional inclusion[cpp.cond]")*s*,
and/or [*has-embed-expression*](#nt:has-embed-expression "15.2Conditional inclusion[cpp.cond]")*s* as unary operator expressions[.](#1.sentence-1)
A [*defined-macro-expression*](#nt:defined-macro-expression "15.2Conditional inclusion[cpp.cond]") shall not appear
within a [*has-include-expression*](#nt:has-include-expression "15.2Conditional inclusion[cpp.cond]") or [*has-embed-expression*](#nt:has-embed-expression "15.2Conditional inclusion[cpp.cond]")[.](#1.sentence-2)
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L401)
A [*defined-macro-expression*](#nt:defined-macro-expression "15.2Conditional inclusion[cpp.cond]") evaluates to 1 if 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]](cpp.import "15.6Header unit importation")),
for example because
it has been the subject of a#define preprocessing directive
without an intervening#undef directive with the same subject identifier), 0 if it is not[.](#2.sentence-1)
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L415)
The header or source file identified by
the parenthesized preprocessing token sequence
in each contained [*has-include-expression*](#nt:has-include-expression "15.2Conditional inclusion[cpp.cond]") is searched for as if that preprocessing token sequence
were the [*pp-tokens*](cpp.pre#nt:pp-tokens "15.1Preamble[cpp.pre]") of a #include directive,
except that no further macro expansion is performed[.](#3.sentence-1)
If the preprocessing token sequence does not consist solely of a [*header-name*](lex.header#nt:header-name "5.6Header names[lex.header]") or cannot be combined ([[cpp.include]](cpp.include "15.3Source file inclusion")) into a single[*header-name*](lex.header#nt:header-name "5.6Header names[lex.header]") preprocessing token, the program is ill-formed[.](#3.sentence-2)
The [*has-include-expression*](#nt:has-include-expression "15.2Conditional inclusion[cpp.cond]") evaluates
to 1 if the search for the source file succeeds, and
to 0 if the search fails[.](#3.sentence-3)
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L429)
The parenthesized preprocessing token sequence of each contained[*has-embed-expression*](#nt:has-embed-expression "15.2Conditional inclusion[cpp.cond]") is processed as if that
preprocessing token sequence were the [*pp-tokens*](cpp.pre#nt:pp-tokens "15.1Preamble[cpp.pre]") of a #embed directive ([[cpp.embed]](cpp.embed "15.4Resource inclusion")),
except that no further macro expansion is performed[.](#4.sentence-1)
The [*has-embed-expression*](#nt:has-embed-expression "15.2Conditional inclusion[cpp.cond]") evaluates to:
- [(4.1)](#4.1)
__STDC_EMBED_FOUND__ if the search for the resource succeeds,
all the given [*embed-parameter*](cpp.pre#nt:embed-parameter "15.1Preamble[cpp.pre]")*s* in the [*embed-parameter-seq*](cpp.pre#nt:embed-parameter-seq "15.1Preamble[cpp.pre]") are supported, and the resource is not empty[.](#4.1.sentence-1)
- [(4.2)](#4.2)
Otherwise, __STDC_EMBED_EMPTY__ if the search for the resource succeeds,
all the given [*embed-parameter*](cpp.pre#nt:embed-parameter "15.1Preamble[cpp.pre]")*s* in the [*embed-parameter-seq*](cpp.pre#nt:embed-parameter-seq "15.1Preamble[cpp.pre]") are supported, and the resource is empty[.](#4.2.sentence-1)
- [(4.3)](#4.3)
Otherwise, __STDC_EMBED_NOT_FOUND__[.](#4.3.sentence-1)
[*Note [1](#note-1)*:
An unrecognized [*embed-parameter*](cpp.pre#nt:embed-parameter "15.1Preamble[cpp.pre]") in an [*has-embed-expression*](#nt:has-embed-expression "15.2Conditional inclusion[cpp.cond]") is not ill-formed and is instead treated as not supported[.](#4.sentence-3)
— *end note*]
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L453)
Each [*has-attribute-expression*](#nt:has-attribute-expression "15.2Conditional inclusion[cpp.cond]") is replaced by
a non-zero [*pp-number*](lex.ppnumber#nt:pp-number "5.7Preprocessing numbers[lex.ppnumber]") matching the form of an [*integer-literal*](lex.icon#nt:integer-literal "5.13.2Integer literals[lex.icon]") if the implementation supports an attribute
with the name specified by interpreting
the [*pp-tokens*](cpp.pre#nt:pp-tokens "15.1Preamble[cpp.pre]"), after macro expansion,
as an [*attribute-token*](dcl.attr.grammar#nt:attribute-token "9.13.1Attribute syntax and semantics[dcl.attr.grammar]"),
and by 0 otherwise[.](#5.sentence-1)
The program is ill-formed if the [*pp-tokens*](cpp.pre#nt:pp-tokens "15.1Preamble[cpp.pre]") do not match the form of an [*attribute-token*](dcl.attr.grammar#nt:attribute-token "9.13.1Attribute syntax and semantics[dcl.attr.grammar]")[.](#5.sentence-2)
[6](#6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L465)
For an attribute specified in this document,
it is implementation-defined
whether the value of the [*has-attribute-expression*](#nt:has-attribute-expression "15.2Conditional inclusion[cpp.cond]") is 0 or is given by Table [21](#tab:cpp.cond.ha "Table 21: __has_­cpp_­attribute values")[.](#6.sentence-1)
For other attributes recognized by the implementation,
the value isimplementation-defined[.](#6.sentence-2)
[*Note [2](#note-2)*:
It is expected
that the availability of an attribute can be detected by any non-zero result[.](#6.sentence-3)
— *end note*]
Table [21](#tab:cpp.cond.ha) — __has_cpp_attribute values [[tab:cpp.cond.ha]](./tab:cpp.cond.ha)
| [🔗](#tab:cpp.cond.ha-row-1)<br>**Attribute** | **Value** |
| --- | --- |
| [🔗](#tab:cpp.cond.ha-row-2)<br>assume | 202207L |
| [🔗](#tab:cpp.cond.ha-row-3)<br>deprecated | 201309L |
| [🔗](#tab:cpp.cond.ha-row-4)<br>fallthrough | 201603L |
| [🔗](#tab:cpp.cond.ha-row-5)<br>indeterminate | 202403L |
| [🔗](#tab:cpp.cond.ha-row-6)<br>likely | 201803L |
| [🔗](#tab:cpp.cond.ha-row-7)<br>maybe_unused | 201603L |
| [🔗](#tab:cpp.cond.ha-row-8)<br>no_unique_address | 201803L |
| [🔗](#tab:cpp.cond.ha-row-9)<br>nodiscard | 201907L |
| [🔗](#tab:cpp.cond.ha-row-10)<br>noreturn | 200809L |
| [🔗](#tab:cpp.cond.ha-row-11)<br>unlikely | 201803L |
[7](#7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L496)
The#ifdef, #ifndef, #elifdef, and #elifndef directives, and
the defined conditional inclusion operator,
shall treat __has_include, __has_embed, and __has_cpp_attribute as if they were the names of defined macros[.](#7.sentence-1)
The identifiers __has_include, __has_embed, and __has_cpp_attribute shall not appear in any context not mentioned in this subclause[.](#7.sentence-2)
[8](#8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L506)
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](lex.token "5.10Tokens[lex.token]")[.](#8.sentence-1)
[9](#9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L512)
Preprocessing directives of the forms
# if [*constant-expression*](expr.const#nt:constant-expression "7.7Constant expressions[expr.const]") [*new-line*](cpp.pre#nt:new-line "15.1Preamble[cpp.pre]") [*group*](cpp.pre#nt:group "15.1Preamble[cpp.pre]")opt
# elif [*constant-expression*](expr.const#nt:constant-expression "7.7Constant expressions[expr.const]") [*new-line*](cpp.pre#nt:new-line "15.1Preamble[cpp.pre]") [*group*](cpp.pre#nt:group "15.1Preamble[cpp.pre]")opt
check whether the controlling constant expression evaluates to nonzero[.](#9.sentence-1)
[10](#10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L522)
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 thedefined unary operator),
just as in normal text[.](#10.sentence-1)
If replacement of macros in the preprocessing tokens following the sequence__has_embed ( and before a matching ) (possibly produced by macro expansion)
encounters a preprocessing token that is one of the [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]")*s*limit, prefix, suffix, or if_empty and that [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]") is defined
as a macro ([[cpp.replace.general]](cpp.replace.general "15.7.1General")), the program is ill-formed[.](#10.sentence-2)
If the preprocessing tokendefined is generated as a result of this replacement process
or use of thedefined unary operator does not match one of the two specified forms
prior to macro replacement,
the program is ill-formed, no diagnostic required[.](#10.sentence-3)
[11](#11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L547)
After all replacements due to macro expansion and
evaluations of[*defined-macro-expression*](#nt:defined-macro-expression "15.2Conditional inclusion[cpp.cond]")*s*,[*has-include-expression*](#nt:has-include-expression "15.2Conditional inclusion[cpp.cond]")*s*,[*has-embed-expression*](#nt:has-embed-expression "15.2Conditional inclusion[cpp.cond]")*s*, and[*has-attribute-expression*](#nt:has-attribute-expression "15.2Conditional inclusion[cpp.cond]")*s* have been performed,
all remaining identifiers and keywords,
except fortrue andfalse,
are replaced with the [*pp-number*](lex.ppnumber#nt:pp-number "5.7Preprocessing numbers[lex.ppnumber]")0,
and then each preprocessing token is converted into a token[.](#11.sentence-1)
[*Note [3](#note-3)*:
An [alternative
token](lex.digraph "5.9Alternative tokens[lex.digraph]") is not an identifier,
even when its spelling consists entirely of letters and underscores[.](#11.sentence-2)
Therefore it is not subject to this replacement[.](#11.sentence-3)
— *end note*]
[12](#12)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L570)
The resulting tokens comprise the controlling constant expression
which is evaluated according to the rules of [[expr.const]](expr.const "7.7Constant expressions") using arithmetic that has at least the ranges specified
in [[support.limits]](support.limits "17.3Implementation properties")[.](#12.sentence-1)
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]](cstdint.syn "17.4.1Header <cstdint> synopsis"))[.](#12.sentence-2)
[*Note [4](#note-4)*:
Thus on an
implementation where std::numeric_limits<int>::max() is 0x7FFF and std::numeric_limits<unsigned int>::max() is 0xFFFF,
the integer literal 0x8000 is signed and positive within a #if expression even though it is unsigned in [translation phase
7](lex.phases "5.2Phases of translation[lex.phases]")[.](#12.sentence-3)
— *end note*]
This includes interpreting [*character-literal*](lex.ccon#nt:character-literal "5.13.3Character literals[lex.ccon]")*s* according to the rules in [[lex.ccon]](lex.ccon "5.13.3Character literals")[.](#12.sentence-4)
[*Note [5](#note-5)*:
The associated character encodings of literals are the same
in #if and #elif directives and in any expression[.](#12.sentence-5)
— *end note*]
Each subexpression with typebool is subjected to integral promotion before processing continues[.](#12.sentence-6)
[13](#13)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L596)
Preprocessing directives of the forms
# ifdef [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]") [*new-line*](cpp.pre#nt:new-line "15.1Preamble[cpp.pre]") [*group*](cpp.pre#nt:group "15.1Preamble[cpp.pre]")opt
# ifndef [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]") [*new-line*](cpp.pre#nt:new-line "15.1Preamble[cpp.pre]") [*group*](cpp.pre#nt:group "15.1Preamble[cpp.pre]")opt
# elifdef [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]") [*new-line*](cpp.pre#nt:new-line "15.1Preamble[cpp.pre]") [*group*](cpp.pre#nt:group "15.1Preamble[cpp.pre]")opt
# elifndef [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]") [*new-line*](cpp.pre#nt:new-line "15.1Preamble[cpp.pre]") [*group*](cpp.pre#nt:group "15.1Preamble[cpp.pre]")opt
check whether the identifier is or is not currently defined as a macro name[.](#13.sentence-1)
Their conditions are equivalent to#if defined [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]"),#if !defined [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]"),#elif defined [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]"), and#elif !defined [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]"),
respectively[.](#13.sentence-2)
[14](#14)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L616)
Each directive's condition is checked in order[.](#14.sentence-1)
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[.](#14.sentence-2)
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[.](#14.sentence-3)
If none of the conditions evaluates to true,
and there is a#elsedirective,
the group controlled by the#else is processed; lacking a#else directive, all the groups until the#endifare skipped[.](#14.sentence-4)[124](#footnote-124 "As indicated by the syntax, a preprocessing token cannot follow a #else or #endif directive before the terminating new-line character. However, comments can appear anywhere in a source file, including within a preprocessing directive.")
[15](#15)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L654)
[*Example [1](#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*]
[16](#16)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L677)
[*Example [2](#example-2)*:
This demonstrates a way to use the attribute [[acme::deprecated]] only if it is available[.](#16.sentence-1)
#if __has_cpp_attribute(acme::deprecated)# define ATTR_DEPRECATED(msg) [[acme::deprecated(msg)]]#else# define ATTR_DEPRECATED(msg) [[deprecated(msg)]]#endif ATTR_DEPRECATED("This function is deprecated") void anvil(); — *end example*]
[123)](#footnote-123)[123)](#footnoteref-123)
Because the controlling constant expression is evaluated
during translation phase 4,
all identifiers either are or are not macro names —
there simply are no keywords, enumeration constants, etc[.](#footnote-123.sentence-1)
[124)](#footnote-124)[124)](#footnoteref-124)
As indicated by the syntax,
a preprocessing token cannot follow a#else or#endif directive before the terminating new-line character[.](#footnote-124.sentence-1)
However,
comments can appear anywhere in a source file,
including within a preprocessing directive[.](#footnote-124.sentence-2)

353
cppdraft/cpp/embed.md Normal file
View File

@@ -0,0 +1,353 @@
[cpp.embed]
# 15 Preprocessing directives [[cpp]](./#cpp)
## 15.4 Resource inclusion [cpp.embed]
### [15.4.1](#gen) General [[cpp.embed.gen]](cpp.embed.gen)
[1](#gen-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L845)
A [*bracket resource search*](#def:search,bracket_resource "15.4.1General[cpp.embed.gen]") for a sequence of characters
searches a sequence of places for a resource identified uniquely
by that sequence of characters[.](#gen-1.sentence-1)
How the places are determined or the resource identified
is implementation-defined[.](#gen-1.sentence-2)
[2](#gen-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L852)
A [*quote resource search*](#def:search,quote_resource "15.4.1General[cpp.embed.gen]") for a sequence of characters
attempts to identify a resource that is named by the sequence of characters[.](#gen-2.sentence-1)
The named resource is searched for
in an implementation-defined manner[.](#gen-2.sentence-2)
If the implementation does not support a quote resource search
for that sequence of characters, or if the search fails,
the result of the quote resource search
is the result of a bracket resource search for the same sequence of characters[.](#gen-2.sentence-3)
[3](#gen-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L862)
A preprocessing directive of the form
# embed [*header-name*](lex.header#nt:header-name "5.6Header names[lex.header]") [*pp-tokens*](cpp.pre#nt:pp-tokens "15.1Preamble[cpp.pre]")opt [*new-line*](cpp.pre#nt:new-line "15.1Preamble[cpp.pre]")
causes the replacement of that directive
by preprocessing tokens derived from data
in the resource identified by [*header-name*](lex.header#nt:header-name "5.6Header names[lex.header]"),
as specified below[.](#gen-3.sentence-1)
[4](#gen-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L872)
If the [*header-name*](lex.header#nt:header-name "5.6Header names[lex.header]") is of the form
< [*h-char-sequence*](lex.header#nt:h-char-sequence "5.6Header names[lex.header]") >
the resource is identified by a bracket resource search
for the sequence of characters of the [*h-char-sequence*](lex.header#nt:h-char-sequence "5.6Header names[lex.header]")[.](#gen-4.sentence-1)
[5](#gen-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L880)
If the [*header-name*](lex.header#nt:header-name "5.6Header names[lex.header]") is of the form
" [*q-char-sequence*](lex.header#nt:q-char-sequence "5.6Header names[lex.header]") "
the resource is identified by a quote resource search
for the sequence of characters of the [*q-char-sequence*](lex.header#nt:q-char-sequence "5.6Header names[lex.header]")[.](#gen-5.sentence-1)
[6](#gen-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L888)
If a bracket resource search fails,
or if a quote or bracket resource search identifies a resource
that cannot be processed by the implementation, the program is ill-formed[.](#gen-6.sentence-1)
[*Note [1](#gen-note-1)*:
If the resource cannot be processed, the program is ill-formed
even when processing #embed with limit(0) ([[cpp.embed.param.limit]](#param.limit "15.4.2.1limit parameter"))
or evaluating __has_embed[.](#gen-6.sentence-2)
— *end note*]
[7](#gen-7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L898)
*Recommended practice*: A mechanism similar to, but distinct from, theimplementation-defined
search paths used for #include ([[cpp.include]](cpp.include "15.3Source file inclusion"))
is encouraged[.](#gen-7.sentence-1)
[8](#gen-8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L904)
Either form of the #embed directive processes the[*pp-tokens*](cpp.pre#nt:pp-tokens "15.1Preamble[cpp.pre]"), if present, just as in normal text[.](#gen-8.sentence-1)
The [*pp-tokens*](cpp.pre#nt:pp-tokens "15.1Preamble[cpp.pre]") shall then have the form[*embed-parameter-seq*](cpp.pre#nt:embed-parameter-seq "15.1Preamble[cpp.pre]")[.](#gen-8.sentence-2)
[9](#gen-9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L910)
A resource is a source of data accessible from the translation environment[.](#gen-9.sentence-1)
A resource has an [*implementation-resource-width*](#def:implementation-resource-width "15.4.1General[cpp.embed.gen]"), which is theimplementation-defined
size in bits of the resource[.](#gen-9.sentence-2)
If the implementation-resource-width is not an integral multiple ofCHAR_BIT, the program is ill-formed[.](#gen-9.sentence-3)
Let [*implementation-resource-count*](#def:implementation-resource-count "15.4.1General[cpp.embed.gen]") be
implementation-resource-width divided by CHAR_BIT[.](#gen-9.sentence-4)
Every resource also has a [*resource-count*](#def:resource-count "15.4.1General[cpp.embed.gen]"), which is
- [(9.1)](#gen-9.1)
the value as computed from the optionally-provided limit[*embed-parameter*](cpp.pre#nt:embed-parameter "15.1Preamble[cpp.pre]") ([[cpp.embed.param.limit]](#param.limit "15.4.2.1limit parameter")), if present;
- [(9.2)](#gen-9.2)
otherwise, the implementation-resource-count.
A resource is empty if the resource-count is zero[.](#gen-9.sentence-6)
[10](#gen-10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L931)
[*Example [1](#gen-example-1)*: // ill-formed if the implementation-resource-width is 6 bits#embed "6_bits.bin" — *end example*]
[11](#gen-11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L939)
The #embed directive is replaced by a comma-separated list of integer
literals of type int, unless otherwise modified by embed
parameters ([[cpp.embed.param]](#param "15.4.2Embed parameters"))[.](#gen-11.sentence-1)
[12](#gen-12)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L944)
The integer literals in the comma-separated list correspond to
resource-count consecutive calls to std::fgetc ([[cstdio.syn]](cstdio.syn "31.13.1Header <cstdio> synopsis"))
from the resource, as a binary file[.](#gen-12.sentence-1)
If any call to std::fgetc returns EOF, the program is
ill-formed[.](#gen-12.sentence-2)
[13](#gen-13)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L951)
*Recommended practice*: The value of each integer literal should closely represent
the bit stream of the resource unmodified[.](#gen-13.sentence-1)
This can require an implementation to consider potential differences between
translation and execution environments, as well as any other applicable
sources of mismatch[.](#gen-13.sentence-2)
[*Example [2](#gen-example-2)*: #include <cstring>#include <cstddef>#include <fstream>#include <vector>#include <cassert>int main() {// If the file is the same as the resource in the translation environment, no assert in this program should fail.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); // same file in execution environment as was embedded 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](#gen-example-3)*: int i = {#embed "i.dat"}; // well-formed if i.dat produces a single valueint i2 =#embed "i.dat" ; // also well-formed if i.dat produces a single valuestruct s {double a, b, c; struct { double e, f, g; } x; double h, i, j;};
s x = {// well-formed if the directive produces nine or fewer values#embed "s.dat"}; — *end example*]
[14](#gen-14)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L1012)
A preprocessing directive of the form
# embed [*pp-tokens*](cpp.pre#nt:pp-tokens "15.1Preamble[cpp.pre]") [*new-line*](cpp.pre#nt:new-line "15.1Preamble[cpp.pre]")
(that does not match the previous form) is permitted[.](#gen-14.sentence-1)
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)[.](#gen-14.sentence-2)
Then, an attempt is made to form a [*header-name*](lex.header#nt:header-name "5.6Header names[lex.header]") preprocessing token ([[lex.header]](lex.header "5.6Header names")) from the whitespace and the characters
of the spellings of the resulting sequence of preprocessing tokens immediately after embed;
the treatment of whitespace
is implementation-defined[.](#gen-14.sentence-3)
If the attempt succeeds, the directive with the so-formed [*header-name*](lex.header#nt:header-name "5.6Header names[lex.header]") is processed as specified for the previous form[.](#gen-14.sentence-4)
Otherwise, the program is ill-formed[.](#gen-14.sentence-5)
[*Note [2](#gen-note-2)*:
Adjacent [*string-literal*](lex.string#nt:string-literal "5.13.5String literals[lex.string]")*s* are not concatenated into a single[*string-literal*](lex.string#nt:string-literal "5.13.5String literals[lex.string]") (see the translation phases in [[lex.phases]](lex.phases "5.2Phases of translation"));
thus, an expansion that results in two [*string-literal*](lex.string#nt:string-literal "5.13.5String literals[lex.string]")*s* is an
invalid directive[.](#gen-14.sentence-6)
— *end note*]
Any further processing as in normal text described for the previous
form is not performed[.](#gen-14.sentence-7)
[*Note [3](#gen-note-3)*:
That is, processing as in normal text happens once and only once for the entire
directive[.](#gen-14.sentence-8)
— *end note*]
[*Example [4](#gen-example-4)*:
If the directive matches the second form, the whole directive is replaced[.](#gen-14.sentence-9)
If the directive matches the first form, everything after the name is replaced[.](#gen-14.sentence-10)
#define EMPTY#define X myfile#define Y rsc#define Z 42#embed <myfile.rsc> prefix(Z)#embed EMPTY <X.Y> prefix(Z) is equivalent to:#embed <myfile.rsc> prefix(42)#embed <myfile.rsc> prefix(42)
— *end example*]
### [15.4.2](#param) Embed parameters [[cpp.embed.param]](cpp.embed.param)
#### [15.4.2.1](#param.limit) limit parameter [[cpp.embed.param.limit]](cpp.embed.param.limit)
[1](#param.limit-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L1063)
An [*embed-parameter*](cpp.pre#nt:embed-parameter "15.1Preamble[cpp.pre]") of the formlimit ( [*pp-balanced-token-seq*](cpp.pre#nt:pp-balanced-token-seq "15.1Preamble[cpp.pre]") ) specifies the
maximum possible number of elements in the comma-delimited list[.](#param.limit-1.sentence-1)
It shall appear at most once in the [*embed-parameter-seq*](cpp.pre#nt:embed-parameter-seq "15.1Preamble[cpp.pre]")[.](#param.limit-1.sentence-2)
The preprocessing token defined shall not appear in the[*pp-balanced-token-seq*](cpp.pre#nt:pp-balanced-token-seq "15.1Preamble[cpp.pre]")[.](#param.limit-1.sentence-3)
[2](#param.limit-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L1072)
The [*pp-balanced-token-seq*](cpp.pre#nt:pp-balanced-token-seq "15.1Preamble[cpp.pre]") is evaluated as a[*constant-expression*](expr.const#nt:constant-expression "7.7Constant expressions[expr.const]") using the rules as described in conditional
inclusion ([[cpp.cond]](cpp.cond "15.2Conditional inclusion")), but without being processed as in normal text an
additional time[.](#param.limit-2.sentence-1)
[*Example [1](#param.limit-example-1)*: #undef DATA_LIMIT#if __has_embed(<data.dat> limit(DATA_LIMIT))#endif
is equivalent to:
#if __has_embed(<data.dat> limit(0))#endif — *end example*]
[*Example [2](#param.limit-example-2)*: #embed <data.dat> limit(__has_include("a.h"))#if __has_embed(<data.dat> limit(__has_include("a.h")))// ill-formed: __has_include ([[cpp.cond]](cpp.cond "15.2Conditional inclusion")) cannot appear here#endif — *end example*]
[3](#param.limit-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L1103)
The [*constant-expression*](expr.const#nt:constant-expression "7.7Constant expressions[expr.const]") shall be an integral constant expression
whose value is greater than or equal to zero[.](#param.limit-3.sentence-1)
The resource-count ([[cpp.embed.gen]](#gen "15.4.1General")) becomes
implementation-resource-count, if the value of the[*constant-expression*](expr.const#nt:constant-expression "7.7Constant expressions[expr.const]") is greater than
implementation-resource-count; otherwise, the value of the[*constant-expression*](expr.const#nt:constant-expression "7.7Constant expressions[expr.const]")[.](#param.limit-3.sentence-2)
[*Example [3](#param.limit-example-3)*: constexpr unsigned char sound_signature[] = {// a hypothetical resource capable of expanding to four or more elements#embed <sdk/jump.wav> limit(2+2)};
static_assert(sizeof(sound_signature) == 4); // OK — *end example*]
#### [15.4.2.2](#param.prefix) prefix parameter [[cpp.embed.param.prefix]](cpp.embed.param.prefix)
[1](#param.prefix-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L1123)
An [*embed-parameter*](cpp.pre#nt:embed-parameter "15.1Preamble[cpp.pre]") of the form
prefix ( [*pp-balanced-token-seq*](cpp.pre#nt:pp-balanced-token-seq "15.1Preamble[cpp.pre]")opt )
shall appear at most once in the [*embed-parameter-seq*](cpp.pre#nt:embed-parameter-seq "15.1Preamble[cpp.pre]")[.](#param.prefix-1.sentence-1)
[2](#param.prefix-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L1130)
If the resource is empty, this [*embed-parameter*](cpp.pre#nt:embed-parameter "15.1Preamble[cpp.pre]") is ignored[.](#param.prefix-2.sentence-1)
Otherwise, the [*pp-balanced-token-seq*](cpp.pre#nt:pp-balanced-token-seq "15.1Preamble[cpp.pre]") is placed immediately
before the comma-delimited list of integral literals[.](#param.prefix-2.sentence-2)
#### [15.4.2.3](#param.suffix) suffix parameter [[cpp.embed.param.suffix]](cpp.embed.param.suffix)
[1](#param.suffix-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L1136)
An [*embed-parameter*](cpp.pre#nt:embed-parameter "15.1Preamble[cpp.pre]") of the form
suffix ( [*pp-balanced-token-seq*](cpp.pre#nt:pp-balanced-token-seq "15.1Preamble[cpp.pre]")opt )
shall appear at most once in the [*embed-parameter-seq*](cpp.pre#nt:embed-parameter-seq "15.1Preamble[cpp.pre]")[.](#param.suffix-1.sentence-1)
[2](#param.suffix-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L1143)
If the resource is empty, this [*embed-parameter*](cpp.pre#nt:embed-parameter "15.1Preamble[cpp.pre]") is ignored[.](#param.suffix-2.sentence-1)
Otherwise, the [*pp-balanced-token-seq*](cpp.pre#nt:pp-balanced-token-seq "15.1Preamble[cpp.pre]") is placed immediately after
the comma-delimited list of the integral constant expressions[.](#param.suffix-2.sentence-2)
[*Example [1](#param.suffix-example-1)*: constexpr unsigned char whl[] = {#embed "ches.glsl" \
prefix(0xEF, 0xBB, 0xBF, ) /* a sequence of bytes */ \
suffix(,)0};// always null-terminated, contains the sequence if not emptyconstexpr 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](#param.if.empty) if_empty parameter [[cpp.embed.param.if.empty]](cpp.embed.param.if.empty)
[1](#param.if.empty-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L1166)
An embed-parameter of the form
if_empty ( [*pp-balanced-token-seq*](cpp.pre#nt:pp-balanced-token-seq "15.1Preamble[cpp.pre]")opt )
shall appear at most once in the [*embed-parameter-seq*](cpp.pre#nt:embed-parameter-seq "15.1Preamble[cpp.pre]")[.](#param.if.empty-1.sentence-1)
[2](#param.if.empty-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L1173)
If the resource is not empty, this [*embed-parameter*](cpp.pre#nt:embed-parameter "15.1Preamble[cpp.pre]") is ignored[.](#param.if.empty-2.sentence-1)
Otherwise, the #embed directive is replaced by the[*pp-balanced-token-seq*](cpp.pre#nt:pp-balanced-token-seq "15.1Preamble[cpp.pre]")[.](#param.if.empty-2.sentence-2)
[*Example [1](#param.if.empty-example-1)*:
limit(0) affects when a resource is considered empty[.](#param.if.empty-2.sentence-3)
Therefore, the following program:
#embed </owo/uwurandom> \
if_empty(42203) limit(0) expands to42203
— *end example*]
[*Example [2](#param.if.empty-example-2)*:
This resource is considered empty due to the limit(0) [*embed-parameter*](cpp.pre#nt:embed-parameter "15.1Preamble[cpp.pre]"),
always, including in __has_embed clauses[.](#param.if.empty-2.sentence-6)
int infinity_zero () {#if __has_embed(</owo/uwurandom> limit(0) prefix(some tokens)) == __STDC_EMBED_EMPTY__ // if </owo/uwurandom> exists, this conditional inclusion branch is taken and the function returns 0.return 0;#else// otherwise, the resource does not exist#error "The resource does not exist"#endif} — *end example*]

223
cppdraft/cpp/embed/gen.md Normal file
View File

@@ -0,0 +1,223 @@
[cpp.embed.gen]
# 15 Preprocessing directives [[cpp]](./#cpp)
## 15.4 Resource inclusion [[cpp.embed]](cpp.embed#gen)
### 15.4.1 General [cpp.embed.gen]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L845)
A [*bracket resource search*](#def:search,bracket_resource "15.4.1General[cpp.embed.gen]") for a sequence of characters
searches a sequence of places for a resource identified uniquely
by that sequence of characters[.](#1.sentence-1)
How the places are determined or the resource identified
is implementation-defined[.](#1.sentence-2)
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L852)
A [*quote resource search*](#def:search,quote_resource "15.4.1General[cpp.embed.gen]") for a sequence of characters
attempts to identify a resource that is named by the sequence of characters[.](#2.sentence-1)
The named resource is searched for
in an implementation-defined manner[.](#2.sentence-2)
If the implementation does not support a quote resource search
for that sequence of characters, or if the search fails,
the result of the quote resource search
is the result of a bracket resource search for the same sequence of characters[.](#2.sentence-3)
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L862)
A preprocessing directive of the form
# embed [*header-name*](lex.header#nt:header-name "5.6Header names[lex.header]") [*pp-tokens*](cpp.pre#nt:pp-tokens "15.1Preamble[cpp.pre]")opt [*new-line*](cpp.pre#nt:new-line "15.1Preamble[cpp.pre]")
causes the replacement of that directive
by preprocessing tokens derived from data
in the resource identified by [*header-name*](lex.header#nt:header-name "5.6Header names[lex.header]"),
as specified below[.](#3.sentence-1)
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L872)
If the [*header-name*](lex.header#nt:header-name "5.6Header names[lex.header]") is of the form
< [*h-char-sequence*](lex.header#nt:h-char-sequence "5.6Header names[lex.header]") >
the resource is identified by a bracket resource search
for the sequence of characters of the [*h-char-sequence*](lex.header#nt:h-char-sequence "5.6Header names[lex.header]")[.](#4.sentence-1)
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L880)
If the [*header-name*](lex.header#nt:header-name "5.6Header names[lex.header]") is of the form
" [*q-char-sequence*](lex.header#nt:q-char-sequence "5.6Header names[lex.header]") "
the resource is identified by a quote resource search
for the sequence of characters of the [*q-char-sequence*](lex.header#nt:q-char-sequence "5.6Header names[lex.header]")[.](#5.sentence-1)
[6](#6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L888)
If a bracket resource search fails,
or if a quote or bracket resource search identifies a resource
that cannot be processed by the implementation, the program is ill-formed[.](#6.sentence-1)
[*Note [1](#note-1)*:
If the resource cannot be processed, the program is ill-formed
even when processing #embed with limit(0) ([[cpp.embed.param.limit]](cpp.embed.param.limit "15.4.2.1limit parameter"))
or evaluating __has_embed[.](#6.sentence-2)
— *end note*]
[7](#7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L898)
*Recommended practice*: A mechanism similar to, but distinct from, theimplementation-defined
search paths used for #include ([[cpp.include]](cpp.include "15.3Source file inclusion"))
is encouraged[.](#7.sentence-1)
[8](#8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L904)
Either form of the #embed directive processes the[*pp-tokens*](cpp.pre#nt:pp-tokens "15.1Preamble[cpp.pre]"), if present, just as in normal text[.](#8.sentence-1)
The [*pp-tokens*](cpp.pre#nt:pp-tokens "15.1Preamble[cpp.pre]") shall then have the form[*embed-parameter-seq*](cpp.pre#nt:embed-parameter-seq "15.1Preamble[cpp.pre]")[.](#8.sentence-2)
[9](#9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L910)
A resource is a source of data accessible from the translation environment[.](#9.sentence-1)
A resource has an [*implementation-resource-width*](#def:implementation-resource-width "15.4.1General[cpp.embed.gen]"), which is theimplementation-defined
size in bits of the resource[.](#9.sentence-2)
If the implementation-resource-width is not an integral multiple ofCHAR_BIT, the program is ill-formed[.](#9.sentence-3)
Let [*implementation-resource-count*](#def:implementation-resource-count "15.4.1General[cpp.embed.gen]") be
implementation-resource-width divided by CHAR_BIT[.](#9.sentence-4)
Every resource also has a [*resource-count*](#def:resource-count "15.4.1General[cpp.embed.gen]"), which is
- [(9.1)](#9.1)
the value as computed from the optionally-provided limit[*embed-parameter*](cpp.pre#nt:embed-parameter "15.1Preamble[cpp.pre]") ([[cpp.embed.param.limit]](cpp.embed.param.limit "15.4.2.1limit parameter")), if present;
- [(9.2)](#9.2)
otherwise, the implementation-resource-count.
A resource is empty if the resource-count is zero[.](#9.sentence-6)
[10](#10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L931)
[*Example [1](#example-1)*: // ill-formed if the implementation-resource-width is 6 bits#embed "6_bits.bin" — *end example*]
[11](#11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L939)
The #embed directive is replaced by a comma-separated list of integer
literals of type int, unless otherwise modified by embed
parameters ([[cpp.embed.param]](cpp.embed.param "15.4.2Embed parameters"))[.](#11.sentence-1)
[12](#12)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L944)
The integer literals in the comma-separated list correspond to
resource-count consecutive calls to std::fgetc ([[cstdio.syn]](cstdio.syn "31.13.1Header <cstdio> synopsis"))
from the resource, as a binary file[.](#12.sentence-1)
If any call to std::fgetc returns EOF, the program is
ill-formed[.](#12.sentence-2)
[13](#13)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L951)
*Recommended practice*: The value of each integer literal should closely represent
the bit stream of the resource unmodified[.](#13.sentence-1)
This can require an implementation to consider potential differences between
translation and execution environments, as well as any other applicable
sources of mismatch[.](#13.sentence-2)
[*Example [2](#example-2)*: #include <cstring>#include <cstddef>#include <fstream>#include <vector>#include <cassert>int main() {// If the file is the same as the resource in the translation environment, no assert in this program should fail.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); // same file in execution environment as was embedded 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](#example-3)*: int i = {#embed "i.dat"}; // well-formed if i.dat produces a single valueint i2 =#embed "i.dat" ; // also well-formed if i.dat produces a single valuestruct s {double a, b, c; struct { double e, f, g; } x; double h, i, j;};
s x = {// well-formed if the directive produces nine or fewer values#embed "s.dat"}; — *end example*]
[14](#14)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L1012)
A preprocessing directive of the form
# embed [*pp-tokens*](cpp.pre#nt:pp-tokens "15.1Preamble[cpp.pre]") [*new-line*](cpp.pre#nt:new-line "15.1Preamble[cpp.pre]")
(that does not match the previous form) is permitted[.](#14.sentence-1)
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)[.](#14.sentence-2)
Then, an attempt is made to form a [*header-name*](lex.header#nt:header-name "5.6Header names[lex.header]") preprocessing token ([[lex.header]](lex.header "5.6Header names")) from the whitespace and the characters
of the spellings of the resulting sequence of preprocessing tokens immediately after embed;
the treatment of whitespace
is implementation-defined[.](#14.sentence-3)
If the attempt succeeds, the directive with the so-formed [*header-name*](lex.header#nt:header-name "5.6Header names[lex.header]") is processed as specified for the previous form[.](#14.sentence-4)
Otherwise, the program is ill-formed[.](#14.sentence-5)
[*Note [2](#note-2)*:
Adjacent [*string-literal*](lex.string#nt:string-literal "5.13.5String literals[lex.string]")*s* are not concatenated into a single[*string-literal*](lex.string#nt:string-literal "5.13.5String literals[lex.string]") (see the translation phases in [[lex.phases]](lex.phases "5.2Phases of translation"));
thus, an expansion that results in two [*string-literal*](lex.string#nt:string-literal "5.13.5String literals[lex.string]")*s* is an
invalid directive[.](#14.sentence-6)
— *end note*]
Any further processing as in normal text described for the previous
form is not performed[.](#14.sentence-7)
[*Note [3](#note-3)*:
That is, processing as in normal text happens once and only once for the entire
directive[.](#14.sentence-8)
— *end note*]
[*Example [4](#example-4)*:
If the directive matches the second form, the whole directive is replaced[.](#14.sentence-9)
If the directive matches the first form, everything after the name is replaced[.](#14.sentence-10)
#define EMPTY#define X myfile#define Y rsc#define Z 42#embed <myfile.rsc> prefix(Z)#embed EMPTY <X.Y> prefix(Z) is equivalent to:#embed <myfile.rsc> prefix(42)#embed <myfile.rsc> prefix(42)
— *end example*]

135
cppdraft/cpp/embed/param.md Normal file
View File

@@ -0,0 +1,135 @@
[cpp.embed.param]
# 15 Preprocessing directives [[cpp]](./#cpp)
## 15.4 Resource inclusion [[cpp.embed]](cpp.embed#param)
### 15.4.2 Embed parameters [cpp.embed.param]
#### [15.4.2.1](#limit) limit parameter [[cpp.embed.param.limit]](cpp.embed.param.limit)
[1](#limit-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L1063)
An [*embed-parameter*](cpp.pre#nt:embed-parameter "15.1Preamble[cpp.pre]") of the formlimit ( [*pp-balanced-token-seq*](cpp.pre#nt:pp-balanced-token-seq "15.1Preamble[cpp.pre]") ) specifies the
maximum possible number of elements in the comma-delimited list[.](#limit-1.sentence-1)
It shall appear at most once in the [*embed-parameter-seq*](cpp.pre#nt:embed-parameter-seq "15.1Preamble[cpp.pre]")[.](#limit-1.sentence-2)
The preprocessing token defined shall not appear in the[*pp-balanced-token-seq*](cpp.pre#nt:pp-balanced-token-seq "15.1Preamble[cpp.pre]")[.](#limit-1.sentence-3)
[2](#limit-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L1072)
The [*pp-balanced-token-seq*](cpp.pre#nt:pp-balanced-token-seq "15.1Preamble[cpp.pre]") is evaluated as a[*constant-expression*](expr.const#nt:constant-expression "7.7Constant expressions[expr.const]") using the rules as described in conditional
inclusion ([[cpp.cond]](cpp.cond "15.2Conditional inclusion")), but without being processed as in normal text an
additional time[.](#limit-2.sentence-1)
[*Example [1](#limit-example-1)*: #undef DATA_LIMIT#if __has_embed(<data.dat> limit(DATA_LIMIT))#endif
is equivalent to:
#if __has_embed(<data.dat> limit(0))#endif — *end example*]
[*Example [2](#limit-example-2)*: #embed <data.dat> limit(__has_include("a.h"))#if __has_embed(<data.dat> limit(__has_include("a.h")))// ill-formed: __has_include ([[cpp.cond]](cpp.cond "15.2Conditional inclusion")) cannot appear here#endif — *end example*]
[3](#limit-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L1103)
The [*constant-expression*](expr.const#nt:constant-expression "7.7Constant expressions[expr.const]") shall be an integral constant expression
whose value is greater than or equal to zero[.](#limit-3.sentence-1)
The resource-count ([[cpp.embed.gen]](cpp.embed.gen "15.4.1General")) becomes
implementation-resource-count, if the value of the[*constant-expression*](expr.const#nt:constant-expression "7.7Constant expressions[expr.const]") is greater than
implementation-resource-count; otherwise, the value of the[*constant-expression*](expr.const#nt:constant-expression "7.7Constant expressions[expr.const]")[.](#limit-3.sentence-2)
[*Example [3](#limit-example-3)*: constexpr unsigned char sound_signature[] = {// a hypothetical resource capable of expanding to four or more elements#embed <sdk/jump.wav> limit(2+2)};
static_assert(sizeof(sound_signature) == 4); // OK — *end example*]
#### [15.4.2.2](#prefix) prefix parameter [[cpp.embed.param.prefix]](cpp.embed.param.prefix)
[1](#prefix-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L1123)
An [*embed-parameter*](cpp.pre#nt:embed-parameter "15.1Preamble[cpp.pre]") of the form
prefix ( [*pp-balanced-token-seq*](cpp.pre#nt:pp-balanced-token-seq "15.1Preamble[cpp.pre]")opt )
shall appear at most once in the [*embed-parameter-seq*](cpp.pre#nt:embed-parameter-seq "15.1Preamble[cpp.pre]")[.](#prefix-1.sentence-1)
[2](#prefix-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L1130)
If the resource is empty, this [*embed-parameter*](cpp.pre#nt:embed-parameter "15.1Preamble[cpp.pre]") is ignored[.](#prefix-2.sentence-1)
Otherwise, the [*pp-balanced-token-seq*](cpp.pre#nt:pp-balanced-token-seq "15.1Preamble[cpp.pre]") is placed immediately
before the comma-delimited list of integral literals[.](#prefix-2.sentence-2)
#### [15.4.2.3](#suffix) suffix parameter [[cpp.embed.param.suffix]](cpp.embed.param.suffix)
[1](#suffix-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L1136)
An [*embed-parameter*](cpp.pre#nt:embed-parameter "15.1Preamble[cpp.pre]") of the form
suffix ( [*pp-balanced-token-seq*](cpp.pre#nt:pp-balanced-token-seq "15.1Preamble[cpp.pre]")opt )
shall appear at most once in the [*embed-parameter-seq*](cpp.pre#nt:embed-parameter-seq "15.1Preamble[cpp.pre]")[.](#suffix-1.sentence-1)
[2](#suffix-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L1143)
If the resource is empty, this [*embed-parameter*](cpp.pre#nt:embed-parameter "15.1Preamble[cpp.pre]") is ignored[.](#suffix-2.sentence-1)
Otherwise, the [*pp-balanced-token-seq*](cpp.pre#nt:pp-balanced-token-seq "15.1Preamble[cpp.pre]") is placed immediately after
the comma-delimited list of the integral constant expressions[.](#suffix-2.sentence-2)
[*Example [1](#suffix-example-1)*: constexpr unsigned char whl[] = {#embed "ches.glsl" \
prefix(0xEF, 0xBB, 0xBF, ) /* a sequence of bytes */ \
suffix(,)0};// always null-terminated, contains the sequence if not emptyconstexpr 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) if_empty parameter [[cpp.embed.param.if.empty]](cpp.embed.param.if.empty)
[1](#if.empty-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L1166)
An embed-parameter of the form
if_empty ( [*pp-balanced-token-seq*](cpp.pre#nt:pp-balanced-token-seq "15.1Preamble[cpp.pre]")opt )
shall appear at most once in the [*embed-parameter-seq*](cpp.pre#nt:embed-parameter-seq "15.1Preamble[cpp.pre]")[.](#if.empty-1.sentence-1)
[2](#if.empty-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L1173)
If the resource is not empty, this [*embed-parameter*](cpp.pre#nt:embed-parameter "15.1Preamble[cpp.pre]") is ignored[.](#if.empty-2.sentence-1)
Otherwise, the #embed directive is replaced by the[*pp-balanced-token-seq*](cpp.pre#nt:pp-balanced-token-seq "15.1Preamble[cpp.pre]")[.](#if.empty-2.sentence-2)
[*Example [1](#if.empty-example-1)*:
limit(0) affects when a resource is considered empty[.](#if.empty-2.sentence-3)
Therefore, the following program:
#embed </owo/uwurandom> \
if_empty(42203) limit(0) expands to42203
— *end example*]
[*Example [2](#if.empty-example-2)*:
This resource is considered empty due to the limit(0) [*embed-parameter*](cpp.pre#nt:embed-parameter "15.1Preamble[cpp.pre]"),
always, including in __has_embed clauses[.](#if.empty-2.sentence-6)
int infinity_zero () {#if __has_embed(</owo/uwurandom> limit(0) prefix(some tokens)) == __STDC_EMBED_EMPTY__ // if </owo/uwurandom> exists, this conditional inclusion branch is taken and the function returns 0.return 0;#else// otherwise, the resource does not exist#error "The resource does not exist"#endif} — *end example*]

View File

@@ -0,0 +1,45 @@
[cpp.embed.param.if.empty]
# 15 Preprocessing directives [[cpp]](./#cpp)
## 15.4 Resource inclusion [[cpp.embed]](cpp.embed#param.if.empty)
### 15.4.2 Embed parameters [[cpp.embed.param]](cpp.embed.param#if.empty)
#### 15.4.2.4 if_empty parameter [cpp.embed.param.if.empty]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L1166)
An embed-parameter of the form
if_empty ( [*pp-balanced-token-seq*](cpp.pre#nt:pp-balanced-token-seq "15.1Preamble[cpp.pre]")opt )
shall appear at most once in the [*embed-parameter-seq*](cpp.pre#nt:embed-parameter-seq "15.1Preamble[cpp.pre]")[.](#1.sentence-1)
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L1173)
If the resource is not empty, this [*embed-parameter*](cpp.pre#nt:embed-parameter "15.1Preamble[cpp.pre]") is ignored[.](#2.sentence-1)
Otherwise, the #embed directive is replaced by the[*pp-balanced-token-seq*](cpp.pre#nt:pp-balanced-token-seq "15.1Preamble[cpp.pre]")[.](#2.sentence-2)
[*Example [1](#example-1)*:
limit(0) affects when a resource is considered empty[.](#2.sentence-3)
Therefore, the following program:
#embed </owo/uwurandom> \
if_empty(42203) limit(0) expands to42203
— *end example*]
[*Example [2](#example-2)*:
This resource is considered empty due to the limit(0) [*embed-parameter*](cpp.pre#nt:embed-parameter "15.1Preamble[cpp.pre]"),
always, including in __has_embed clauses[.](#2.sentence-6)
int infinity_zero () {#if __has_embed(</owo/uwurandom> limit(0) prefix(some tokens)) == __STDC_EMBED_EMPTY__ // if </owo/uwurandom> exists, this conditional inclusion branch is taken and the function returns 0.return 0;#else// otherwise, the resource does not exist#error "The resource does not exist"#endif} — *end example*]

View File

@@ -0,0 +1,51 @@
[cpp.embed.param.limit]
# 15 Preprocessing directives [[cpp]](./#cpp)
## 15.4 Resource inclusion [[cpp.embed]](cpp.embed#param.limit)
### 15.4.2 Embed parameters [[cpp.embed.param]](cpp.embed.param#limit)
#### 15.4.2.1 limit parameter [cpp.embed.param.limit]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L1063)
An [*embed-parameter*](cpp.pre#nt:embed-parameter "15.1Preamble[cpp.pre]") of the formlimit ( [*pp-balanced-token-seq*](cpp.pre#nt:pp-balanced-token-seq "15.1Preamble[cpp.pre]") ) specifies the
maximum possible number of elements in the comma-delimited list[.](#1.sentence-1)
It shall appear at most once in the [*embed-parameter-seq*](cpp.pre#nt:embed-parameter-seq "15.1Preamble[cpp.pre]")[.](#1.sentence-2)
The preprocessing token defined shall not appear in the[*pp-balanced-token-seq*](cpp.pre#nt:pp-balanced-token-seq "15.1Preamble[cpp.pre]")[.](#1.sentence-3)
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L1072)
The [*pp-balanced-token-seq*](cpp.pre#nt:pp-balanced-token-seq "15.1Preamble[cpp.pre]") is evaluated as a[*constant-expression*](expr.const#nt:constant-expression "7.7Constant expressions[expr.const]") using the rules as described in conditional
inclusion ([[cpp.cond]](cpp.cond "15.2Conditional inclusion")), but without being processed as in normal text an
additional time[.](#2.sentence-1)
[*Example [1](#example-1)*: #undef DATA_LIMIT#if __has_embed(<data.dat> limit(DATA_LIMIT))#endif
is equivalent to:
#if __has_embed(<data.dat> limit(0))#endif — *end example*]
[*Example [2](#example-2)*: #embed <data.dat> limit(__has_include("a.h"))#if __has_embed(<data.dat> limit(__has_include("a.h")))// ill-formed: __has_include ([[cpp.cond]](cpp.cond "15.2Conditional inclusion")) cannot appear here#endif — *end example*]
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L1103)
The [*constant-expression*](expr.const#nt:constant-expression "7.7Constant expressions[expr.const]") shall be an integral constant expression
whose value is greater than or equal to zero[.](#3.sentence-1)
The resource-count ([[cpp.embed.gen]](cpp.embed.gen "15.4.1General")) becomes
implementation-resource-count, if the value of the[*constant-expression*](expr.const#nt:constant-expression "7.7Constant expressions[expr.const]") is greater than
implementation-resource-count; otherwise, the value of the[*constant-expression*](expr.const#nt:constant-expression "7.7Constant expressions[expr.const]")[.](#3.sentence-2)
[*Example [3](#example-3)*: constexpr unsigned char sound_signature[] = {// a hypothetical resource capable of expanding to four or more elements#embed <sdk/jump.wav> limit(2+2)};
static_assert(sizeof(sound_signature) == 4); // OK — *end example*]

View File

@@ -0,0 +1,28 @@
[cpp.embed.param.prefix]
# 15 Preprocessing directives [[cpp]](./#cpp)
## 15.4 Resource inclusion [[cpp.embed]](cpp.embed#param.prefix)
### 15.4.2 Embed parameters [[cpp.embed.param]](cpp.embed.param#prefix)
#### 15.4.2.2 prefix parameter [cpp.embed.param.prefix]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L1123)
An [*embed-parameter*](cpp.pre#nt:embed-parameter "15.1Preamble[cpp.pre]") of the form
prefix ( [*pp-balanced-token-seq*](cpp.pre#nt:pp-balanced-token-seq "15.1Preamble[cpp.pre]")opt )
shall appear at most once in the [*embed-parameter-seq*](cpp.pre#nt:embed-parameter-seq "15.1Preamble[cpp.pre]")[.](#1.sentence-1)
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L1130)
If the resource is empty, this [*embed-parameter*](cpp.pre#nt:embed-parameter "15.1Preamble[cpp.pre]") is ignored[.](#2.sentence-1)
Otherwise, the [*pp-balanced-token-seq*](cpp.pre#nt:pp-balanced-token-seq "15.1Preamble[cpp.pre]") is placed immediately
before the comma-delimited list of integral literals[.](#2.sentence-2)

View File

@@ -0,0 +1,32 @@
[cpp.embed.param.suffix]
# 15 Preprocessing directives [[cpp]](./#cpp)
## 15.4 Resource inclusion [[cpp.embed]](cpp.embed#param.suffix)
### 15.4.2 Embed parameters [[cpp.embed.param]](cpp.embed.param#suffix)
#### 15.4.2.3 suffix parameter [cpp.embed.param.suffix]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L1136)
An [*embed-parameter*](cpp.pre#nt:embed-parameter "15.1Preamble[cpp.pre]") of the form
suffix ( [*pp-balanced-token-seq*](cpp.pre#nt:pp-balanced-token-seq "15.1Preamble[cpp.pre]")opt )
shall appear at most once in the [*embed-parameter-seq*](cpp.pre#nt:embed-parameter-seq "15.1Preamble[cpp.pre]")[.](#1.sentence-1)
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L1143)
If the resource is empty, this [*embed-parameter*](cpp.pre#nt:embed-parameter "15.1Preamble[cpp.pre]") is ignored[.](#2.sentence-1)
Otherwise, the [*pp-balanced-token-seq*](cpp.pre#nt:pp-balanced-token-seq "15.1Preamble[cpp.pre]") is placed immediately after
the comma-delimited list of the integral constant expressions[.](#2.sentence-2)
[*Example [1](#example-1)*: constexpr unsigned char whl[] = {#embed "ches.glsl" \
prefix(0xEF, 0xBB, 0xBF, ) /* a sequence of bytes */ \
suffix(,)0};// always null-terminated, contains the sequence if not emptyconstexpr 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*]

29
cppdraft/cpp/error.md Normal file
View File

@@ -0,0 +1,29 @@
[cpp.error]
# 15 Preprocessing directives [[cpp]](./#cpp)
## 15.9 Diagnostic directives [cpp.error]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L2126)
A preprocessing directive of the form
# error [*pp-tokens*](cpp.pre#nt:pp-tokens "15.1Preamble[cpp.pre]")opt [*new-line*](cpp.pre#nt:new-line "15.1Preamble[cpp.pre]")
renders the program ill-formed[.](#1.sentence-1)
A preprocessing directive of the form
# warning [*pp-tokens*](cpp.pre#nt:pp-tokens "15.1Preamble[cpp.pre]")opt [*new-line*](cpp.pre#nt:new-line "15.1Preamble[cpp.pre]")
requires the implementation to produce at least one diagnostic message
for the preprocessing translation unit ([[intro.compliance.general]](intro.compliance.general "4.1.1General"))[.](#1.sentence-2)
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L2139)
*Recommended practice*: Any diagnostic message caused by either of these directives
should include the specified sequence of preprocessing tokens[.](#2.sentence-1)

177
cppdraft/cpp/import.md Normal file
View File

@@ -0,0 +1,177 @@
[cpp.import]
# 15 Preprocessing directives [[cpp]](./#cpp)
## 15.6 Header unit importation [cpp.import]
[pp-import:](#nt:pp-import "15.6Header unit importation[cpp.import]")
exportopt import [*header-name*](lex.header#nt:header-name "5.6Header names[lex.header]") [*pp-tokens*](cpp.pre#nt:pp-tokens "15.1Preamble[cpp.pre]")opt ; [*new-line*](cpp.pre#nt:new-line "15.1Preamble[cpp.pre]")
exportopt import [*header-name-tokens*](cpp.cond#nt:header-name-tokens "15.2Conditional inclusion[cpp.cond]") [*pp-tokens*](cpp.pre#nt:pp-tokens "15.1Preamble[cpp.pre]")opt ; [*new-line*](cpp.pre#nt:new-line "15.1Preamble[cpp.pre]")
exportopt import [*pp-tokens*](cpp.pre#nt:pp-tokens "15.1Preamble[cpp.pre]") ; [*new-line*](cpp.pre#nt:new-line "15.1Preamble[cpp.pre]")
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L1278)
A [*pp-import*](#nt:pp-import "15.6Header unit importation[cpp.import]") shall not
appear in a context where import or (if it is the first preprocessing token of the [*pp-import*](#nt:pp-import "15.6Header unit importation[cpp.import]")) export is an identifier defined as an object-like macro[.](#1.sentence-1)
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L1284)
The preprocessing tokens after the import preprocessing token
in the import [*control-line*](cpp.pre#nt:control-line "15.1Preamble[cpp.pre]") 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)[.](#2.sentence-1)
[*Note [1](#note-1)*:
An import directive
matching the first two forms of a [*pp-import*](#nt:pp-import "15.6Header unit importation[cpp.import]") instructs the preprocessor to import macros
from the header unit ([[module.import]](module.import "10.3Import declaration"))
denoted by the [*header-name*](lex.header#nt:header-name "5.6Header names[lex.header]"),
as described below[.](#2.sentence-2)
— *end note*]
The [*point of macro import*](#def:macro,point_of_import "15.6Header unit importation[cpp.import]") for the
first two forms of [*pp-import*](#nt:pp-import "15.6Header unit importation[cpp.import]") is
immediately after the [*new-line*](cpp.pre#nt:new-line "15.1Preamble[cpp.pre]") terminating
the [*pp-import*](#nt:pp-import "15.6Header unit importation[cpp.import]")[.](#2.sentence-3)
The last form of [*pp-import*](#nt:pp-import "15.6Header unit importation[cpp.import]") is only considered
if the first two forms did not match, and
does not have a point of macro import[.](#2.sentence-4)
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L1307)
If a [*pp-import*](#nt:pp-import "15.6Header unit importation[cpp.import]") is produced by source file inclusion
(including by the rewrite produced
when a #include directive names an importable header)
while processing the [*group*](cpp.pre#nt:group "15.1Preamble[cpp.pre]") of a [*module-file*](cpp.pre#nt:module-file "15.1Preamble[cpp.pre]"),
the program is ill-formed[.](#3.sentence-1)
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L1314)
In all three forms of [*pp-import*](#nt:pp-import "15.6Header unit importation[cpp.import]"),
the import and export (if it exists) preprocessing tokens
are replaced by the *import-keyword* and*export-keyword* preprocessing tokens respectively[.](#4.sentence-1)
[*Note [2](#note-2)*:
This makes the line no longer a directive
so it is not removed at the end of phase 4[.](#4.sentence-2)
— *end note*]
Additionally, in the second form of [*pp-import*](#nt:pp-import "15.6Header unit importation[cpp.import]"),
a [*header-name*](lex.header#nt:header-name "5.6Header names[lex.header]") token is formed as if
the [*header-name-tokens*](cpp.cond#nt:header-name-tokens "15.2Conditional inclusion[cpp.cond]") were the [*pp-tokens*](cpp.pre#nt:pp-tokens "15.1Preamble[cpp.pre]") of a #include directive[.](#4.sentence-3)
The [*header-name-tokens*](cpp.cond#nt:header-name-tokens "15.2Conditional inclusion[cpp.cond]") are replaced by
the [*header-name*](lex.header#nt:header-name "5.6Header names[lex.header]") token[.](#4.sentence-4)
[*Note [3](#note-3)*:
This ensures that imports are treated consistently by
the preprocessor and later phases of translation[.](#4.sentence-5)
— *end note*]
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L1334)
Each #define directive encountered when preprocessing
each translation unit in a program results in a distinct[*macro definition*](#def:macro,definition "15.6Header unit importation[cpp.import]")[.](#5.sentence-1)
[*Note [4](#note-4)*:
A predefined macro name ([[cpp.predefined]](cpp.predefined "15.12Predefined macro names"))
is not introduced by a #define directive[.](#5.sentence-2)
Implementations providing mechanisms to predefine additional macros
are encouraged to not treat them
as being introduced by a #define directive[.](#5.sentence-3)
— *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:
- [(5.1)](#5.1)
The [*point of definition*](#def:macro,point_of_definition "15.6Header unit importation[cpp.import]") of a macro definition within a translation unit T is
* [(5.1.1)](#5.1.1)
if the #define directive of the macro definition occurs within T,
the point at which that directive occurs, or otherwise,
* [(5.1.2)](#5.1.2)
if the macro name is not lexically identical to a keyword ([[lex.key]](lex.key "5.12Keywords"))
or to the [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]")*s* 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[.](#5.1.sentence-1)
In the latter case, the macro is said
to be [*imported*](#def:macro,import "15.6Header unit importation[cpp.import]") from the header unit[.](#5.1.sentence-2)
- [(5.2)](#5.2)
The [*point of undefinition*](#def:macro,point_of_undefinition "15.6Header unit importation[cpp.import]") of 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[.](#5.2.sentence-1)
[6](#6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L1375)
A macro definition is [*active*](#def:macro,active "15.6Header unit importation[cpp.import]") 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[.](#6.sentence-1)
[7](#7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L1382)
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]](cpp.replace "15.7Macro replacement"))[.](#7.sentence-1)
[*Note [5](#note-5)*:
The relative order of [*pp-import*](#nt:pp-import "15.6Header unit importation[cpp.import]")*s* has no bearing on whether a
particular macro definition is active[.](#7.sentence-2)
— *end note*]
[8](#8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L1391)
[*Example [1](#example-1)*:
Importable header "a.h":#define X 123 // #1#define Y 45 // #2#define Z a // #3#undef X // point of undefinition of #1 in "a.h"
Importable header "b.h":import "a.h"; // point of definition of #1, #2, and #3, point of undefinition of #1 in "b.h"#define X 456 // OK, #1 is not active#define Y 6 // error: #2 is active
Importable header "c.h":#define Y 45 // #4#define Z c // #5
Importable header "d.h":import "c.h"; // point of definition of #4 and #5 in "d.h"
Importable header "e.h":import "a.h"; // point of definition of #1, #2, and #3, point of undefinition of #1 in "e.h"import "d.h"; // point of definition of #4 and #5 in "e.h"int a = Y; // OK, active macro definitions #2 and #4 are valid redefinitionsint c = Z; // error: active macro definitions #3 and #5 are not valid redefinitions of Z
Module unit f:export module f;export import "a.h";
int a = Y; // OK
Translation unit #1:import f;int x = Y; // error: Y is neither a defined macro nor a declared name — *end example*]

172
cppdraft/cpp/include.md Normal file
View File

@@ -0,0 +1,172 @@
[cpp.include]
# 15 Preprocessing directives [[cpp]](./#cpp)
## 15.3 Source file inclusion [cpp.include]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L697)
A [*header search*](#def:search,header "15.3Source file inclusion[cpp.include]") for a sequence of characters
searches a sequence of places for a header
identified uniquely by that sequence of characters[.](#1.sentence-1)
How the places are determined or the header identified
is implementation-defined[.](#1.sentence-2)
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L704)
A [*source file search*](#def:search,source_file "15.3Source file inclusion[cpp.include]") for a sequence of characters
attempts to identify a source file that is named by the sequence of characters[.](#2.sentence-1)
The named source file is searched for
in an implementation-defined manner[.](#2.sentence-2)
If the implementation does not support a source file search
for that sequence of characters, or if the search fails,
the result of the source file search
is the result of a header search for the same sequence of characters[.](#2.sentence-3)
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L714)
A preprocessing directive of the form
# include [*header-name*](lex.header#nt:header-name "5.6Header names[lex.header]") [*new-line*](cpp.pre#nt:new-line "15.1Preamble[cpp.pre]")
causes the replacement of that directive by the entire contents
of the header or source file identified by [*header-name*](lex.header#nt:header-name "5.6Header names[lex.header]")[.](#3.sentence-1)
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L722)
If the [*header-name*](lex.header#nt:header-name "5.6Header names[lex.header]") is of the form
< [*h-char-sequence*](lex.header#nt:h-char-sequence "5.6Header names[lex.header]") >
a header is identified by a header search for the sequence of characters
of the [*h-char-sequence*](lex.header#nt:h-char-sequence "5.6Header names[lex.header]")[.](#4.sentence-1)
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L730)
If the [*header-name*](lex.header#nt:header-name "5.6Header names[lex.header]") is of the form
" [*q-char-sequence*](lex.header#nt:q-char-sequence "5.6Header names[lex.header]") "
the source file or header is identified by a source file search
for the sequence of characters of the [*q-char-sequence*](lex.header#nt:q-char-sequence "5.6Header names[lex.header]")[.](#5.sentence-1)
[6](#6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L738)
If a header search fails, or if a source file search or header search
identifies a header or source file that cannot be processed by the implementation,
the program is ill-formed[.](#6.sentence-1)
[*Note [1](#note-1)*:
If the header or source file cannot be processed,
the program is ill-formed even when evaluating __has_include[.](#6.sentence-2)
— *end note*]
[7](#7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L747)
A preprocessing directive of the form
# include [*pp-tokens*](cpp.pre#nt:pp-tokens "15.1Preamble[cpp.pre]") [*new-line*](cpp.pre#nt:new-line "15.1Preamble[cpp.pre]")
(that does not match the previous form) is permitted[.](#7.sentence-1)
The preprocessing tokens afterinclude 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)[.](#7.sentence-2)
Then, an attempt is made to form a [*header-name*](lex.header#nt:header-name "5.6Header names[lex.header]") preprocessing token ([[lex.header]](lex.header "5.6Header names")) from the whitespace and the characters
of the spellings of the resulting sequence of preprocessing tokens;
the treatment of whitespace
is implementation-defined[.](#7.sentence-3)
If the attempt succeeds, the directive with the so-formed [*header-name*](lex.header#nt:header-name "5.6Header names[lex.header]") is processed as specified for the previous form[.](#7.sentence-4)
Otherwise, the program is ill-formed, no diagnostic required[.](#7.sentence-5)
[*Note [2](#note-2)*:
Adjacent [*string-literal*](lex.string#nt:string-literal "5.13.5String literals[lex.string]")*s* are not concatenated into
a single [*string-literal*](lex.string#nt:string-literal "5.13.5String literals[lex.string]") (see the translation phases in [[lex.phases]](lex.phases "5.2Phases of translation"));
thus, an expansion that results in two [*string-literal*](lex.string#nt:string-literal "5.13.5String literals[lex.string]")*s* is an
invalid directive[.](#7.sentence-6)
— *end note*]
[8](#8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L774)
The implementation shall provide unique mappings for
sequences consisting of one or more[*nondigit*](lex.name#nt:nondigit "5.11Identifiers[lex.name]")*s* or [*digit*](lex.name#nt:digit "5.11Identifiers[lex.name]")*s* ([[lex.name]](lex.name "5.11Identifiers"))
followed by a period
(.)
and a single[*nondigit*](lex.name#nt:nondigit "5.11Identifiers[lex.name]")[.](#8.sentence-1)
The first character shall not be a [*digit*](lex.name#nt:digit "5.11Identifiers[lex.name]")[.](#8.sentence-2)
The implementation may ignore distinctions of alphabetical case[.](#8.sentence-3)
[9](#9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L785)
A#include preprocessing directive may appear
in a source file that has been read because of a#include directive in another file,
up to an implementation-defined nesting limit[.](#9.sentence-1)
[10](#10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L794)
If the header identified by the [*header-name*](lex.header#nt:header-name "5.6Header names[lex.header]") denotes an importable header ([[module.import]](module.import "10.3Import declaration")),
it isimplementation-defined
whether the #include preprocessing directive
is instead replaced by an import directive ([[cpp.import]](cpp.import "15.6Header unit importation")) of the form
import [*header-name*](lex.header#nt:header-name "5.6Header names[lex.header]") ; [*new-line*](cpp.pre#nt:new-line "15.1Preamble[cpp.pre]")
[11](#11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L806)
[*Note [3](#note-3)*:
An implementation can provide a mechanism for making arbitrary
source files available to the < > search[.](#11.sentence-1)
However, using the < > form for headers provided
with the implementation and the " " form for sources
outside the control of the implementation
achieves wider portability[.](#11.sentence-2)
For instance:#include <stdio.h>#include <unistd.h>#include "usefullib.h"#include "myprog.h"
— *end note*]
[12](#12)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L822)
[*Example [1](#example-1)*:
This illustrates macro-replaced#include directives:#if VERSION == 1#define INCFILE "vers1.h"#elif VERSION == 2#define INCFILE "vers2.h" // and so on#else#define INCFILE "versN.h"#endif#include INCFILE
— *end example*]

70
cppdraft/cpp/line.md Normal file
View File

@@ -0,0 +1,70 @@
[cpp.line]
# 15 Preprocessing directives [[cpp]](./#cpp)
## 15.8 Line control [cpp.line]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L2066)
The [*string-literal*](lex.string#nt:string-literal "5.13.5String literals[lex.string]") of a#line directive, if present,
shall be a character string literal[.](#1.sentence-1)
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L2072)
The[*line number*](#def:line_number "15.8Line control[cpp.line]") of 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 1](lex.phases "5.2Phases of translation[lex.phases]") while processing the source file to the current preprocessing token[.](#2.sentence-1)
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L2082)
A preprocessing directive of the form
# line [*digit-sequence*](lex.fcon#nt:digit-sequence "5.13.4Floating-point literals[lex.fcon]") [*new-line*](cpp.pre#nt:new-line "15.1Preamble[cpp.pre]")
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)[.](#3.sentence-1)
If the digit sequence specifies zero
or a number greater than 2147483647,
the program is ill-formed[.](#3.sentence-2)
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L2095)
A preprocessing directive of the form
# line [*digit-sequence*](lex.fcon#nt:digit-sequence "5.13.4Floating-point literals[lex.fcon]") " [*s-char-sequence*](lex.string#nt:s-char-sequence "5.13.5String literals[lex.string]")opt " [*new-line*](cpp.pre#nt:new-line "15.1Preamble[cpp.pre]")
sets the presumed line number similarly and changes the
presumed name of the source file to be the contents
of the character string literal[.](#4.sentence-1)
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L2104)
A preprocessing directive of the form
# line [*pp-tokens*](cpp.pre#nt:pp-tokens "15.1Preamble[cpp.pre]") [*new-line*](cpp.pre#nt:new-line "15.1Preamble[cpp.pre]")
(that does not match one of the two previous forms)
is permitted[.](#5.sentence-1)
The preprocessing tokens afterline on 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)[.](#5.sentence-2)
If the directive resulting after all replacements does not match
one of the two previous forms, the program is ill-formed;
otherwise, the result is processed as appropriate[.](#5.sentence-3)

68
cppdraft/cpp/module.md Normal file
View File

@@ -0,0 +1,68 @@
[cpp.module]
# 15 Preprocessing directives [[cpp]](./#cpp)
## 15.5 Module directive [cpp.module]
[pp-module:](#nt:pp-module "15.5Module directive[cpp.module]")
exportopt module [*pp-tokens*](cpp.pre#nt:pp-tokens "15.1Preamble[cpp.pre]")opt ; [*new-line*](cpp.pre#nt:new-line "15.1Preamble[cpp.pre]")
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L1217)
A [*pp-module*](#nt:pp-module "15.5Module directive[cpp.module]") shall not
appear in a context where module or (if it is the first preprocessing token of the [*pp-module*](#nt:pp-module "15.5Module directive[cpp.module]")) export is an identifier defined as an object-like macro[.](#1.sentence-1)
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L1223)
The [*pp-tokens*](cpp.pre#nt:pp-tokens "15.1Preamble[cpp.pre]"), if any, of a [*pp-module*](#nt:pp-module "15.5Module directive[cpp.module]") shall be of the form:
[*pp-module-name*](#nt:pp-module-name "15.5Module directive[cpp.module]") [*pp-module-partition*](#nt:pp-module-partition "15.5Module directive[cpp.module]")opt [*pp-tokens*](cpp.pre#nt:pp-tokens "15.1Preamble[cpp.pre]")opt
where the [*pp-tokens*](cpp.pre#nt:pp-tokens "15.1Preamble[cpp.pre]") (if any) shall not begin with
a ( preprocessing token and
the grammar non-terminals are defined as:
[pp-module-name:](#nt:pp-module-name "15.5Module directive[cpp.module]")
[*pp-module-name-qualifier*](#nt:pp-module-name-qualifier "15.5Module directive[cpp.module]")opt [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]")
[pp-module-partition:](#nt:pp-module-partition "15.5Module directive[cpp.module]")
: [*pp-module-name-qualifier*](#nt:pp-module-name-qualifier "15.5Module directive[cpp.module]")opt [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]")
[pp-module-name-qualifier:](#nt:pp-module-name-qualifier "15.5Module directive[cpp.module]")
[*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]") .
[*pp-module-name-qualifier*](#nt:pp-module-name-qualifier "15.5Module directive[cpp.module]") [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]") .
No [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]") in
the [*pp-module-name*](#nt:pp-module-name "15.5Module directive[cpp.module]") or [*pp-module-partition*](#nt:pp-module-partition "15.5Module directive[cpp.module]") shall currently be defined as an object-like macro[.](#2.sentence-1)
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L1249)
Any preprocessing tokens after the module preprocessing token
in the module directive are processed just as in normal text[.](#3.sentence-1)
[*Note [1](#note-1)*:
Each identifier currently defined as a macro name
is replaced by its replacement list of preprocessing tokens[.](#3.sentence-2)
— *end note*]
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L1257)
The module and export (if it exists) preprocessing tokens
are replaced by the *module-keyword* and*export-keyword* preprocessing tokens respectively[.](#4.sentence-1)
[*Note [2](#note-2)*:
This makes the line no longer a directive
so it is not removed at the end of phase 4[.](#4.sentence-2)
— *end note*]

15
cppdraft/cpp/null.md Normal file
View File

@@ -0,0 +1,15 @@
[cpp.null]
# 15 Preprocessing directives [[cpp]](./#cpp)
## 15.11 Null directive [cpp.null]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L2162)
A preprocessing directive of the form
# [*new-line*](cpp.pre#nt:new-line "15.1Preamble[cpp.pre]")
has no effect[.](#1.sentence-1)

21
cppdraft/cpp/pragma.md Normal file
View File

@@ -0,0 +1,21 @@
[cpp.pragma]
# 15 Preprocessing directives [[cpp]](./#cpp)
## 15.10 Pragma directive [cpp.pragma]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L2148)
A preprocessing directive of the form
# pragma [*pp-tokens*](cpp.pre#nt:pp-tokens "15.1Preamble[cpp.pre]")opt [*new-line*](cpp.pre#nt:new-line "15.1Preamble[cpp.pre]")
causes the implementation to behave
in an implementation-defined manner[.](#1.sentence-1)
The behavior may cause translation to fail or cause the translator or
the resulting program to behave in a non-conforming manner[.](#1.sentence-2)
Any pragma that is not recognized by the implementation is ignored[.](#1.sentence-3)

37
cppdraft/cpp/pragma/op.md Normal file
View File

@@ -0,0 +1,37 @@
[cpp.pragma.op]
# 15 Preprocessing directives [[cpp]](./#cpp)
## 15.13 Pragma operator [cpp.pragma.op]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L2469)
A unary operator expression of the form:
_Pragma ( [*string-literal*](lex.string#nt:string-literal "5.13.5String literals[lex.string]") )
is processed as follows: The [*string-literal*](lex.string#nt:string-literal "5.13.5String literals[lex.string]") is [*destringized*](#def:destringization "15.13Pragma operator[cpp.pragma.op]") by 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[.](#1.sentence-1)
The resulting sequence of characters is processed through translation phase 3
to produce preprocessing tokens that are executed as if they were the[*pp-tokens*](cpp.pre#nt:pp-tokens "15.1Preamble[cpp.pre]") in a pragma directive[.](#1.sentence-2)
The original four preprocessing
tokens in the unary operator expression are removed[.](#1.sentence-3)
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L2483)
[*Example [1](#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*]

260
cppdraft/cpp/pre.md Normal file
View File

@@ -0,0 +1,260 @@
[cpp.pre]
# 15 Preprocessing directives [[cpp]](./#cpp)
## 15.1 Preamble [cpp.pre]
[preprocessing-file:](#nt:preprocessing-file "15.1Preamble[cpp.pre]")
[*group*](#nt:group "15.1Preamble[cpp.pre]")opt
[*module-file*](#nt:module-file "15.1Preamble[cpp.pre]")
[module-file:](#nt:module-file "15.1Preamble[cpp.pre]")
[*pp-global-module-fragment*](#nt:pp-global-module-fragment "15.1Preamble[cpp.pre]")opt [*pp-module*](cpp.module#nt:pp-module "15.5Module directive[cpp.module]") [*group*](#nt:group "15.1Preamble[cpp.pre]")opt [*pp-private-module-fragment*](#nt:pp-private-module-fragment "15.1Preamble[cpp.pre]")opt
[pp-global-module-fragment:](#nt:pp-global-module-fragment "15.1Preamble[cpp.pre]")
module ; [*new-line*](#nt:new-line "15.1Preamble[cpp.pre]") [*group*](#nt:group "15.1Preamble[cpp.pre]")opt
[pp-private-module-fragment:](#nt:pp-private-module-fragment "15.1Preamble[cpp.pre]")
module : private ; [*new-line*](#nt:new-line "15.1Preamble[cpp.pre]") [*group*](#nt:group "15.1Preamble[cpp.pre]")opt
[group:](#nt:group "15.1Preamble[cpp.pre]")
[*group-part*](#nt:group-part "15.1Preamble[cpp.pre]")
[*group*](#nt:group "15.1Preamble[cpp.pre]") [*group-part*](#nt:group-part "15.1Preamble[cpp.pre]")
[group-part:](#nt:group-part "15.1Preamble[cpp.pre]")
[*control-line*](#nt:control-line "15.1Preamble[cpp.pre]")
[*if-section*](#nt:if-section "15.1Preamble[cpp.pre]")
[*text-line*](#nt:text-line "15.1Preamble[cpp.pre]")
# [*conditionally-supported-directive*](#nt:conditionally-supported-directive "15.1Preamble[cpp.pre]")
[control-line:](#nt:control-line "15.1Preamble[cpp.pre]")
# include [*pp-tokens*](#nt:pp-tokens "15.1Preamble[cpp.pre]") [*new-line*](#nt:new-line "15.1Preamble[cpp.pre]")
[*pp-import*](cpp.import#nt:pp-import "15.6Header unit importation[cpp.import]")
# embed [*pp-tokens*](#nt:pp-tokens "15.1Preamble[cpp.pre]") [*new-line*](#nt:new-line "15.1Preamble[cpp.pre]")
# define [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]") [*replacement-list*](#nt:replacement-list "15.1Preamble[cpp.pre]") [*new-line*](#nt:new-line "15.1Preamble[cpp.pre]")
# define [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]") [*lparen*](#nt:lparen "15.1Preamble[cpp.pre]") [*identifier-list*](#nt:identifier-list "15.1Preamble[cpp.pre]")opt ) [*replacement-list*](#nt:replacement-list "15.1Preamble[cpp.pre]") [*new-line*](#nt:new-line "15.1Preamble[cpp.pre]")
# define [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]") [*lparen*](#nt:lparen "15.1Preamble[cpp.pre]") ... ) [*replacement-list*](#nt:replacement-list "15.1Preamble[cpp.pre]") [*new-line*](#nt:new-line "15.1Preamble[cpp.pre]")
# define [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]") [*lparen*](#nt:lparen "15.1Preamble[cpp.pre]") [*identifier-list*](#nt:identifier-list "15.1Preamble[cpp.pre]") , ... ) [*replacement-list*](#nt:replacement-list "15.1Preamble[cpp.pre]") [*new-line*](#nt:new-line "15.1Preamble[cpp.pre]")
# undef [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]") [*new-line*](#nt:new-line "15.1Preamble[cpp.pre]")
# line [*pp-tokens*](#nt:pp-tokens "15.1Preamble[cpp.pre]") [*new-line*](#nt:new-line "15.1Preamble[cpp.pre]")
# error [*pp-tokens*](#nt:pp-tokens "15.1Preamble[cpp.pre]")opt [*new-line*](#nt:new-line "15.1Preamble[cpp.pre]")
# warning [*pp-tokens*](#nt:pp-tokens "15.1Preamble[cpp.pre]")opt [*new-line*](#nt:new-line "15.1Preamble[cpp.pre]")
# pragma [*pp-tokens*](#nt:pp-tokens "15.1Preamble[cpp.pre]")opt [*new-line*](#nt:new-line "15.1Preamble[cpp.pre]")
# [*new-line*](#nt:new-line "15.1Preamble[cpp.pre]")
[if-section:](#nt:if-section "15.1Preamble[cpp.pre]")
[*if-group*](#nt:if-group "15.1Preamble[cpp.pre]") [*elif-groups*](#nt:elif-groups "15.1Preamble[cpp.pre]")opt [*else-group*](#nt:else-group "15.1Preamble[cpp.pre]")opt [*endif-line*](#nt:endif-line "15.1Preamble[cpp.pre]")
[if-group:](#nt:if-group "15.1Preamble[cpp.pre]")
# if [*constant-expression*](expr.const#nt:constant-expression "7.7Constant expressions[expr.const]") [*new-line*](#nt:new-line "15.1Preamble[cpp.pre]") [*group*](#nt:group "15.1Preamble[cpp.pre]")opt
# ifdef [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]") [*new-line*](#nt:new-line "15.1Preamble[cpp.pre]") [*group*](#nt:group "15.1Preamble[cpp.pre]")opt
# ifndef [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]") [*new-line*](#nt:new-line "15.1Preamble[cpp.pre]") [*group*](#nt:group "15.1Preamble[cpp.pre]")opt
[elif-groups:](#nt:elif-groups "15.1Preamble[cpp.pre]")
[*elif-group*](#nt:elif-group "15.1Preamble[cpp.pre]") [*elif-groups*](#nt:elif-groups "15.1Preamble[cpp.pre]")opt
[elif-group:](#nt:elif-group "15.1Preamble[cpp.pre]")
# elif [*constant-expression*](expr.const#nt:constant-expression "7.7Constant expressions[expr.const]") [*new-line*](#nt:new-line "15.1Preamble[cpp.pre]") [*group*](#nt:group "15.1Preamble[cpp.pre]")opt
# elifdef [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]") [*new-line*](#nt:new-line "15.1Preamble[cpp.pre]") [*group*](#nt:group "15.1Preamble[cpp.pre]")opt
# elifndef [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]") [*new-line*](#nt:new-line "15.1Preamble[cpp.pre]") [*group*](#nt:group "15.1Preamble[cpp.pre]")opt
[else-group:](#nt:else-group "15.1Preamble[cpp.pre]")
# else [*new-line*](#nt:new-line "15.1Preamble[cpp.pre]") [*group*](#nt:group "15.1Preamble[cpp.pre]")opt
[endif-line:](#nt:endif-line "15.1Preamble[cpp.pre]")
# endif [*new-line*](#nt:new-line "15.1Preamble[cpp.pre]")
[text-line:](#nt:text-line "15.1Preamble[cpp.pre]")
[*pp-tokens*](#nt:pp-tokens "15.1Preamble[cpp.pre]")opt [*new-line*](#nt:new-line "15.1Preamble[cpp.pre]")
[conditionally-supported-directive:](#nt:conditionally-supported-directive "15.1Preamble[cpp.pre]")
[*pp-tokens*](#nt:pp-tokens "15.1Preamble[cpp.pre]") [*new-line*](#nt:new-line "15.1Preamble[cpp.pre]")
[lparen:](#nt:lparen "15.1Preamble[cpp.pre]")
a ( character not immediately preceded by whitespace
[identifier-list:](#nt:identifier-list "15.1Preamble[cpp.pre]")
[*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]")
[*identifier-list*](#nt:identifier-list "15.1Preamble[cpp.pre]") , [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]")
[replacement-list:](#nt:replacement-list "15.1Preamble[cpp.pre]")
[*pp-tokens*](#nt:pp-tokens "15.1Preamble[cpp.pre]")opt
[pp-tokens:](#nt:pp-tokens "15.1Preamble[cpp.pre]")
[*preprocessing-token*](lex.pptoken#nt:preprocessing-token "5.5Preprocessing tokens[lex.pptoken]") [*pp-tokens*](#nt:pp-tokens "15.1Preamble[cpp.pre]")opt
[embed-parameter-seq:](#nt:embed-parameter-seq "15.1Preamble[cpp.pre]")
[*embed-parameter*](#nt:embed-parameter "15.1Preamble[cpp.pre]") [*embed-parameter-seq*](#nt:embed-parameter-seq "15.1Preamble[cpp.pre]")opt
[embed-parameter:](#nt:embed-parameter "15.1Preamble[cpp.pre]")
[*embed-standard-parameter*](#nt:embed-standard-parameter "15.1Preamble[cpp.pre]")
[*embed-prefixed-parameter*](#nt:embed-prefixed-parameter "15.1Preamble[cpp.pre]")
[embed-standard-parameter:](#nt:embed-standard-parameter "15.1Preamble[cpp.pre]")
limit ( [*pp-balanced-token-seq*](#nt:pp-balanced-token-seq "15.1Preamble[cpp.pre]") )
prefix ( [*pp-balanced-token-seq*](#nt:pp-balanced-token-seq "15.1Preamble[cpp.pre]")opt )
suffix ( [*pp-balanced-token-seq*](#nt:pp-balanced-token-seq "15.1Preamble[cpp.pre]")opt )
if_empty ( [*pp-balanced-token-seq*](#nt:pp-balanced-token-seq "15.1Preamble[cpp.pre]")opt )
[embed-prefixed-parameter:](#nt:embed-prefixed-parameter "15.1Preamble[cpp.pre]")
[*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]") :: [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]")
[*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]") :: [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]") ( [*pp-balanced-token-seq*](#nt:pp-balanced-token-seq "15.1Preamble[cpp.pre]")opt )
[pp-balanced-token-seq:](#nt:pp-balanced-token-seq "15.1Preamble[cpp.pre]")
[*pp-balanced-token*](#nt:pp-balanced-token "15.1Preamble[cpp.pre]") [*pp-balanced-token-seq*](#nt:pp-balanced-token-seq "15.1Preamble[cpp.pre]")opt
[pp-balanced-token:](#nt:pp-balanced-token "15.1Preamble[cpp.pre]")
( [*pp-balanced-token-seq*](#nt:pp-balanced-token-seq "15.1Preamble[cpp.pre]")opt )
[ [*pp-balanced-token-seq*](#nt:pp-balanced-token-seq "15.1Preamble[cpp.pre]")opt ]
{ [*pp-balanced-token-seq*](#nt:pp-balanced-token-seq "15.1Preamble[cpp.pre]")opt }
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:](#nt:new-line "15.1Preamble[cpp.pre]")
the new-line character
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L176)
A [*preprocessing directive*](#def:preprocessing_directive "15.1Preamble[cpp.pre]") 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*](#def:token,directive-introducing "15.1Preamble[cpp.pre]"),
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
- [(1.1)](#1.1)
a # preprocessing token, or
- [(1.2)](#1.2)
an import preprocessing token
immediately followed on the same logical source line by a[*header-name*](lex.header#nt:header-name "5.6Header names[lex.header]"),<,[*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]"),[*string-literal*](lex.string#nt:string-literal "5.13.5String literals[lex.string]"), or: preprocessing token, or
- [(1.3)](#1.3)
a module preprocessing token
immediately followed on the same logical source line by an[*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]"),:, or; preprocessing token, or
- [(1.4)](#1.4)
an export preprocessing token
immediately followed on the same logical source line by
one of the two preceding forms[.](#1.sentence-1)
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[.](#1.sentence-2)[122](#footnote-122 "Thus, preprocessing directives are commonly called “lines”. These “lines” have no other syntactic significance, as all whitespace is equivalent except in certain situations during preprocessing (see the # character string literal creation operator in [cpp.stringize], for example).")
[*Note [1](#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[.](#1.sentence-3)
— *end note*]
[*Example [1](#example-1)*: # // preprocessing directivemodule ; // preprocessing directiveexport module leftpad; // preprocessing directiveimport <string>; // preprocessing directiveexport import "squee"; // preprocessing directiveimport rightpad; // preprocessing directiveimport :part; // preprocessing directivemodule // not a preprocessing directive ; // not a preprocessing directiveexport // not a preprocessing directiveimport // not a preprocessing directive foo; // not a preprocessing directiveexport // not a preprocessing directiveimport foo; // preprocessing directive (ill-formed at phase 7)import :: // not a preprocessing directiveimport -> // not a preprocessing directive — *end example*]
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L255)
A sequence of preprocessing tokens is only a [*text-line*](#nt:text-line "15.1Preamble[cpp.pre]") if it does not begin with a directive-introducing token[.](#2.sentence-1)
[*Example [2](#example-2)*: using module = int;module i; // not a [*text-line*](#nt:text-line "15.1Preamble[cpp.pre]") and not a [*control-line*](#nt:control-line "15.1Preamble[cpp.pre]")int foo() {return i;}
The example is not a valid [*preprocessing-file*](#nt:preprocessing-file "15.1Preamble[cpp.pre]")[.](#2.sentence-2)
— *end example*]
A sequence of preprocessing tokens is only a [*conditionally-supported-directive*](#nt:conditionally-supported-directive "15.1Preamble[cpp.pre]") if it does not begin with any of the directive names
appearing after a # in the syntax[.](#2.sentence-3)
A [*conditionally-supported-directive*](#nt:conditionally-supported-directive "15.1Preamble[cpp.pre]") is
conditionally-supported withimplementation-defined
semantics[.](#2.sentence-4)
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L276)
If one of the [*pp-tokens*](#nt:pp-tokens "15.1Preamble[cpp.pre]") of a #embed directive
(before macro replacement) is the [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]")limit, prefix, suffix, or if_empty and that [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]") is defined
as a macro ([[cpp.replace.general]](cpp.replace.general "15.7.1General")), the program is ill-formed[.](#3.sentence-1)
Any [*embed-prefixed-parameter*](#nt:embed-prefixed-parameter "15.1Preamble[cpp.pre]") is conditionally-supported,
with implementation-defined semantics[.](#3.sentence-2)
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L285)
At the start of phase 4 of translation,
the [*group*](#nt:group "15.1Preamble[cpp.pre]") of a [*pp-global-module-fragment*](#nt:pp-global-module-fragment "15.1Preamble[cpp.pre]") shall
contain neither a [*text-line*](#nt:text-line "15.1Preamble[cpp.pre]") nor a [*pp-import*](cpp.import#nt:pp-import "15.6Header unit importation[cpp.import]")[.](#4.sentence-1)
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L290)
When in a group that is skipped ([[cpp.cond]](cpp.cond "15.2Conditional inclusion")), the directive
syntax is relaxed to allow any sequence of preprocessing tokens to occur between
the directive name and the following new-line character[.](#5.sentence-1)
[6](#6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L295)
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)[.](#6.sentence-1)
[7](#7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L306)
The implementation can
process and skip sections of source files conditionally,
include other source files,
import macros from header units,
and replace macros[.](#7.sentence-1)
These capabilities are called[*preprocessing*](#def:preprocessing "15.1Preamble[cpp.pre]"),
because conceptually they occur
before translation of the resulting translation unit[.](#7.sentence-2)
[8](#8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L317)
The preprocessing tokens within a preprocessing directive
are not subject to macro expansion unless otherwise stated[.](#8.sentence-1)
[*Example [3](#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 EMPTY has been replaced[.](#8.sentence-2)
— *end example*]
[122)](#footnote-122)[122)](#footnoteref-122)
Thus,
preprocessing directives are commonly called “lines”[.](#footnote-122.sentence-1)
These “lines” have no other syntactic significance,
as all whitespace is equivalent except in certain situations
during preprocessing (see the# character string literal creation operator in [[cpp.stringize]](cpp.stringize "15.7.3The # operator"), for example)[.](#footnote-122.sentence-2)

272
cppdraft/cpp/predefined.md Normal file
View File

@@ -0,0 +1,272 @@
[cpp.predefined]
# 15 Preprocessing directives [[cpp]](./#cpp)
## 15.12 Predefined macro names [cpp.predefined]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L2173)
The following macro names shall be defined by the implementation:
- [(1.1)](#1.1)
__cplusplus
The integer literal 202302L[.](#1.1.sentence-2)
[*Note [1](#note-1)*:
Future revisions of this document will
replace the value of this macro with a greater value[.](#1.1.sentence-3)
— *end note*]
- [(1.2)](#1.2)
The names listed in Table [22](#tab:cpp.predefined.ft "Table 22: Feature-test macros")[.](#1.2.sentence-1)
The macros defined in Table [22](#tab:cpp.predefined.ft "Table 22: Feature-test macros") shall be defined to
the corresponding integer literal[.](#1.2.sentence-2)
[*Note [2](#note-2)*:
Future revisions of this document might replace
the values of these macros with greater values[.](#1.2.sentence-3)
— *end note*]
- [(1.3)](#1.3)
__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 theasctime function,
and the first character ofdd is a space character if the value is less than 10[.](#1.3.sentence-2)
If the date of translation is not available,
an implementation-defined valid date
shall be supplied[.](#1.3.sentence-3)
- [(1.4)](#1.4)
__FILE__
The presumed name of the current source file (a character string
literal)[.](#1.4.sentence-2)[129](#footnote-129 "The presumed source file name can be changed by the #line directive.")
- [(1.5)](#1.5)
__LINE__
The presumed line number (within the current source file) of the current source line
(an integer literal)[.](#1.5.sentence-2)[130](#footnote-130 "The presumed line number can be changed by the #line directive.")
- [(1.6)](#1.6)
__STDC_EMBED_NOT_FOUND__, __STDC_EMBED_FOUND__, and __STDC_EMBED_EMPTY__
The integer literals 0, 1, and 2, respectively[.](#1.6.sentence-2)
[*Note [3](#note-3)*:
These represent values replaced from [*has-embed-expression*](cpp.cond#nt:has-embed-expression "15.2Conditional inclusion[cpp.cond]")*s* ([[cpp.cond]](cpp.cond "15.2Conditional inclusion"))[.](#1.6.sentence-3)
— *end note*]
- [(1.7)](#1.7)
__STDC_HOSTED__
The integer literal 1 if the implementation is a hosted implementation or
the integer literal 0 if it is a freestanding implementation ([[intro.compliance]](intro.compliance "4.1Implementation compliance"))[.](#1.7.sentence-2)
- [(1.8)](#1.8)
__STDCPP_DEFAULT_NEW_ALIGNMENT__
An integer literal of type std::size_t whose value is the alignment guaranteed
by a call to operator new(std::size_t) or operator new[](std::size_t)[.](#1.8.sentence-2)
[*Note [4](#note-4)*:
Larger alignments will be passed tooperator new(std::size_t, std::align_val_t), etc[.](#1.8.sentence-3)
([[expr.new]](expr.new "7.6.2.8New"))[.](#1.8.sentence-4)
— *end note*]
- [(1.9)](#1.9)
__STDCPP_FLOAT16_T__
Defined as the integer literal 1 if and only if the implementation supports
the ISO/IEC 60559 floating-point interchange format binary16
as an extended floating-point type ([[basic.extended.fp]](basic.extended.fp "6.9.3Optional extended floating-point types"))[.](#1.9.sentence-2)
- [(1.10)](#1.10)
__STDCPP_FLOAT32_T__
Defined as the integer literal 1 if and only if the implementation supports
the ISO/IEC 60559 floating-point interchange format binary32
as an extended floating-point type[.](#1.10.sentence-2)
- [(1.11)](#1.11)
__STDCPP_FLOAT64_T__
Defined as the integer literal 1 if and only if the implementation supports
the ISO/IEC 60559 floating-point interchange format binary64
as an extended floating-point type[.](#1.11.sentence-2)
- [(1.12)](#1.12)
__STDCPP_FLOAT128_T__
Defined as the integer literal 1 if and only if the implementation supports
the ISO/IEC 60559 floating-point interchange format binary128
as an extended floating-point type[.](#1.12.sentence-2)
- [(1.13)](#1.13)
__STDCPP_BFLOAT16_T__
Defined as the integer literal 1 if and only if the implementation supports an extended floating-point type
with the properties of the [*typedef-name*](dcl.typedef#nt:typedef-name "9.2.4The typedef specifier[dcl.typedef]") std::bfloat16_t as described in [[basic.extended.fp]](basic.extended.fp "6.9.3Optional extended floating-point types")[.](#1.13.sentence-2)
- [(1.14)](#1.14)
__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 theasctime function[.](#1.14.sentence-2)
If the time of translation is not available,
an implementation-defined valid time shall be supplied[.](#1.14.sentence-3)
Table [22](#tab:cpp.predefined.ft) — Feature-test macros [[tab:cpp.predefined.ft]](./tab:cpp.predefined.ft)
| [🔗](#tab:cpp.predefined.ft-row-1)<br>**Macro name** | **Value** |
| --- | --- |
| [🔗](#tab:cpp.predefined.ft-row-2)<br>__cpp_aggregate_bases | 201603L |
| [🔗](#tab:cpp.predefined.ft-row-3)<br>__cpp_aggregate_nsdmi | 201304L |
| [🔗](#tab:cpp.predefined.ft-row-4)<br>__cpp_aggregate_paren_init | 201902L |
| [🔗](#tab:cpp.predefined.ft-row-5)<br>__cpp_alias_templates | 200704L |
| [🔗](#tab:cpp.predefined.ft-row-6)<br>__cpp_aligned_new | 201606L |
| [🔗](#tab:cpp.predefined.ft-row-7)<br>__cpp_attributes | 200809L |
| [🔗](#tab:cpp.predefined.ft-row-8)<br>__cpp_auto_cast | 202110L |
| [🔗](#tab:cpp.predefined.ft-row-9)<br>__cpp_binary_literals | 201304L |
| [🔗](#tab:cpp.predefined.ft-row-10)<br>__cpp_capture_star_this | 201603L |
| [🔗](#tab:cpp.predefined.ft-row-11)<br>__cpp_char8_t | 202207L |
| [🔗](#tab:cpp.predefined.ft-row-12)<br>__cpp_concepts | 202002L |
| [🔗](#tab:cpp.predefined.ft-row-13)<br>__cpp_conditional_explicit | 201806L |
| [🔗](#tab:cpp.predefined.ft-row-14)<br>__cpp_constexpr | 202406L |
| [🔗](#tab:cpp.predefined.ft-row-15)<br>__cpp_constexpr_dynamic_alloc | 201907L |
| [🔗](#tab:cpp.predefined.ft-row-16)<br>__cpp_constexpr_exceptions | 202411L |
| [🔗](#tab:cpp.predefined.ft-row-17)<br>__cpp_constexpr_in_decltype | 201711L |
| [🔗](#tab:cpp.predefined.ft-row-18)<br>__cpp_constexpr_virtual_inheritance | 202506L |
| [🔗](#tab:cpp.predefined.ft-row-19)<br>__cpp_consteval | 202211L |
| [🔗](#tab:cpp.predefined.ft-row-20)<br>__cpp_constinit | 201907L |
| [🔗](#tab:cpp.predefined.ft-row-21)<br>__cpp_contracts | 202502L |
| [🔗](#tab:cpp.predefined.ft-row-22)<br>__cpp_decltype | 200707L |
| [🔗](#tab:cpp.predefined.ft-row-23)<br>__cpp_decltype_auto | 201304L |
| [🔗](#tab:cpp.predefined.ft-row-24)<br>__cpp_deduction_guides | 201907L |
| [🔗](#tab:cpp.predefined.ft-row-25)<br>__cpp_delegating_constructors | 200604L |
| [🔗](#tab:cpp.predefined.ft-row-26)<br>__cpp_deleted_function | 202403L |
| [🔗](#tab:cpp.predefined.ft-row-27)<br>__cpp_designated_initializers | 201707L |
| [🔗](#tab:cpp.predefined.ft-row-28)<br>__cpp_enumerator_attributes | 201411L |
| [🔗](#tab:cpp.predefined.ft-row-29)<br>__cpp_expansion_statements | 202506L |
| [🔗](#tab:cpp.predefined.ft-row-30)<br>__cpp_explicit_this_parameter | 202110L |
| [🔗](#tab:cpp.predefined.ft-row-31)<br>__cpp_fold_expressions | 201603L |
| [🔗](#tab:cpp.predefined.ft-row-32)<br>__cpp_generic_lambdas | 201707L |
| [🔗](#tab:cpp.predefined.ft-row-33)<br>__cpp_guaranteed_copy_elision | 201606L |
| [🔗](#tab:cpp.predefined.ft-row-34)<br>__cpp_hex_float | 201603L |
| [🔗](#tab:cpp.predefined.ft-row-35)<br>__cpp_if_consteval | 202106L |
| [🔗](#tab:cpp.predefined.ft-row-36)<br>__cpp_if_constexpr | 201606L |
| [🔗](#tab:cpp.predefined.ft-row-37)<br>__cpp_impl_coroutine | 201902L |
| [🔗](#tab:cpp.predefined.ft-row-38)<br>__cpp_impl_destroying_delete | 201806L |
| [🔗](#tab:cpp.predefined.ft-row-39)<br>__cpp_impl_three_way_comparison | 201907L |
| [🔗](#tab:cpp.predefined.ft-row-40)<br>__cpp_impl_reflection | 202506L |
| [🔗](#tab:cpp.predefined.ft-row-41)<br>__cpp_implicit_move | 202207L |
| [🔗](#tab:cpp.predefined.ft-row-42)<br>__cpp_inheriting_constructors | 201511L |
| [🔗](#tab:cpp.predefined.ft-row-43)<br>__cpp_init_captures | 201803L |
| [🔗](#tab:cpp.predefined.ft-row-44)<br>__cpp_initializer_lists | 200806L |
| [🔗](#tab:cpp.predefined.ft-row-45)<br>__cpp_inline_variables | 201606L |
| [🔗](#tab:cpp.predefined.ft-row-46)<br>__cpp_lambdas | 200907L |
| [🔗](#tab:cpp.predefined.ft-row-47)<br>__cpp_modules | 201907L |
| [🔗](#tab:cpp.predefined.ft-row-48)<br>__cpp_multidimensional_subscript | 202211L |
| [🔗](#tab:cpp.predefined.ft-row-49)<br>__cpp_named_character_escapes | 202207L |
| [🔗](#tab:cpp.predefined.ft-row-50)<br>__cpp_namespace_attributes | 201411L |
| [🔗](#tab:cpp.predefined.ft-row-51)<br>__cpp_noexcept_function_type | 201510L |
| [🔗](#tab:cpp.predefined.ft-row-52)<br>__cpp_nontype_template_args | 201911L |
| [🔗](#tab:cpp.predefined.ft-row-53)<br>__cpp_nontype_template_parameter_auto | 201606L |
| [🔗](#tab:cpp.predefined.ft-row-54)<br>__cpp_nsdmi | 200809L |
| [🔗](#tab:cpp.predefined.ft-row-55)<br>__cpp_pack_indexing | 202311L |
| [🔗](#tab:cpp.predefined.ft-row-56)<br>__cpp_placeholder_variables | 202306L |
| [🔗](#tab:cpp.predefined.ft-row-57)<br>__cpp_pp_embed | 202502L |
| [🔗](#tab:cpp.predefined.ft-row-58)<br>__cpp_range_based_for | 202211L |
| [🔗](#tab:cpp.predefined.ft-row-59)<br>__cpp_raw_strings | 200710L |
| [🔗](#tab:cpp.predefined.ft-row-60)<br>__cpp_ref_qualifiers | 200710L |
| [🔗](#tab:cpp.predefined.ft-row-61)<br>__cpp_return_type_deduction | 201304L |
| [🔗](#tab:cpp.predefined.ft-row-62)<br>__cpp_rvalue_references | 200610L |
| [🔗](#tab:cpp.predefined.ft-row-63)<br>__cpp_size_t_suffix | 202011L |
| [🔗](#tab:cpp.predefined.ft-row-64)<br>__cpp_sized_deallocation | 201309L |
| [🔗](#tab:cpp.predefined.ft-row-65)<br>__cpp_static_assert | 202306L |
| [🔗](#tab:cpp.predefined.ft-row-66)<br>__cpp_static_call_operator | 202207L |
| [🔗](#tab:cpp.predefined.ft-row-67)<br>__cpp_structured_bindings | 202411L |
| [🔗](#tab:cpp.predefined.ft-row-68)<br>__cpp_template_parameters | 202502L |
| [🔗](#tab:cpp.predefined.ft-row-69)<br>__cpp_template_template_args | 201611L |
| [🔗](#tab:cpp.predefined.ft-row-70)<br>__cpp_threadsafe_static_init | 200806L |
| [🔗](#tab:cpp.predefined.ft-row-71)<br>__cpp_trivial_relocatability | 202502L |
| [🔗](#tab:cpp.predefined.ft-row-72)<br>__cpp_trivial_union | 202502L |
| [🔗](#tab:cpp.predefined.ft-row-73)<br>__cpp_unicode_characters | 200704L |
| [🔗](#tab:cpp.predefined.ft-row-74)<br>__cpp_unicode_literals | 200710L |
| [🔗](#tab:cpp.predefined.ft-row-75)<br>__cpp_user_defined_literals | 200809L |
| [🔗](#tab:cpp.predefined.ft-row-76)<br>__cpp_using_enum | 201907L |
| [🔗](#tab:cpp.predefined.ft-row-77)<br>__cpp_variable_templates | 201304L |
| [🔗](#tab:cpp.predefined.ft-row-78)<br>__cpp_variadic_friend | 202403L |
| [🔗](#tab:cpp.predefined.ft-row-79)<br>__cpp_variadic_templates | 200704L |
| [🔗](#tab:cpp.predefined.ft-row-80)<br>__cpp_variadic_using | 201611L |
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L2405)
The following macro names are conditionally defined by the implementation:
- [(2.1)](#2.1)
__STDC__
Whether __STDC__ is predefined and if so, what its value is,
are implementation-defined[.](#2.1.sentence-2)
- [(2.2)](#2.2)
__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[.](#2.2.sentence-2)
- [(2.3)](#2.3)
__STDC_VERSION__
Whether __STDC_VERSION__ is predefined and if so, what its value is,
are implementation-defined[.](#2.3.sentence-2)
- [(2.4)](#2.4)
__STDC_ISO_10646__
An integer literal of the form yyyymmL (for example, 199712L)[.](#2.4.sentence-2)
Whether __STDC_ISO_10646__ is predefined and
if so, what its value is,
are implementation-defined[.](#2.4.sentence-3)
- [(2.5)](#2.5)
__STDCPP_THREADS__
Defined, and has the value integer literal 1, if and only if a program
can have more than one [thread of execution](intro.multithread "6.10.2Multi-threaded executions and data races[intro.multithread]")[.](#2.5.sentence-2)
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L2443)
The values of the predefined macros
(except for__FILE__ and__LINE__)
remain constant throughout the translation unit[.](#3.sentence-1)
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L2451)
If any of the pre-defined macro names in this subclause,
or the identifierdefined,
is the subject of a#define or a#undef preprocessing directive,
the program is ill-formed[.](#4.sentence-1)
Any other predefined macro names shall begin with a
leading underscore followed by an uppercase letter or a second
underscore[.](#4.sentence-2)
[129)](#footnote-129)[129)](#footnoteref-129)
The presumed source file name can be changed by the #line directive[.](#footnote-129.sentence-1)
[130)](#footnote-130)[130)](#footnoteref-130)
The presumed line number can be changed by the #line directive[.](#footnote-130.sentence-1)

571
cppdraft/cpp/replace.md Normal file
View File

@@ -0,0 +1,571 @@
[cpp.replace]
# 15 Preprocessing directives [[cpp]](./#cpp)
## 15.7 Macro replacement [cpp.replace]
### [15.7.1](#general) General [[cpp.replace.general]](cpp.replace.general)
[1](#general-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L1443)
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[.](#general-1.sentence-1)
[2](#general-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L1450)
An identifier currently defined as anobject-like macro (see below) may be redefined by another#define preprocessing 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[.](#general-2.sentence-1)
Likewise, an identifier currently defined as afunction-like macro (see below) may be redefined by another#define preprocessing 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[.](#general-2.sentence-2)
[3](#general-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L1468)
[*Example [1](#general-example-1)*:
The following sequence is valid:#define OBJ_LIKE (1-1)#define OBJ_LIKE /* whitespace */ (1-1) /* other */#define FUNC_LIKE(a) ( a )#define FUNC_LIKE( a )( /* note the whitespace */ \
a /* other stuff on this line
*/ )
But the following redefinitions are invalid:#define OBJ_LIKE (0) // different token sequence#define OBJ_LIKE (1 - 1) // different whitespace#define FUNC_LIKE(b) ( a ) // different parameter usage#define FUNC_LIKE(b) ( b ) // different parameter spelling
— *end example*]
[4](#general-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L1488)
There shall be whitespace between the identifier and the replacement list
in the definition of an object-like macro[.](#general-4.sentence-1)
[5](#general-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L1493)
If the [*identifier-list*](cpp.pre#nt:identifier-list "15.1Preamble[cpp.pre]") 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[.](#general-5.sentence-1)
Otherwise, there shall be at least as many arguments in the invocation as there are
parameters in the macro definition (excluding the ...)[.](#general-5.sentence-2)
There
shall exist a) preprocessing token that terminates the invocation[.](#general-5.sentence-3)
[6](#general-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L1505)
The identifiers __VA_ARGS__ and __VA_OPT__ shall occur only in the [*replacement-list*](cpp.pre#nt:replacement-list "15.1Preamble[cpp.pre]") of a function-like macro that uses the ellipsis notation in the parameters[.](#general-6.sentence-1)
[7](#general-7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L1512)
A parameter identifier in a function-like macro
shall be uniquely declared within its scope[.](#general-7.sentence-1)
[8](#general-8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L1516)
The identifier immediately following thedefine is called the[*macro name*](#def:macro,name "15.7.1General[cpp.replace.general]")[.](#general-8.sentence-1)
There is one name space for macro names[.](#general-8.sentence-2)
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[.](#general-8.sentence-3)
[9](#general-9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L1527)
A translation unit shall not #define or #undef names lexically identical
to keywords,
to the identifiers listed in Table [4](lex.name#tab:lex.name.special "Table 4: Identifiers with special meaning"), or
to the [*attribute-token*](dcl.attr.grammar#nt:attribute-token "9.13.1Attribute syntax and semantics[dcl.attr.grammar]")*s* described in [[dcl.attr]](dcl.attr "9.13Attributes"),
except that the names likely and unlikely may be
defined as function-like macros[.](#general-9.sentence-1)
[10](#general-10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L1537)
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[.](#general-10.sentence-1)
[11](#general-11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L1547)
A preprocessing directive of the form
# define [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]") [*replacement-list*](cpp.pre#nt:replacement-list "15.1Preamble[cpp.pre]") [*new-line*](cpp.pre#nt:new-line "15.1Preamble[cpp.pre]")
defines an[*object-like macro*](#def:macro,object-like "15.7.1General[cpp.replace.general]") that
causes each subsequent instance of the macro name[125](#footnote-125 "Since, by macro-replacement time, all character-literals and string-literals are preprocessing tokens, not sequences possibly containing identifier-like subsequences (see [lex.phases], translation phases), they are never scanned for macro names or parameters.") to be replaced by the replacement list of preprocessing tokens
that constitute the remainder of the directive[.](#general-11.sentence-1)[126](#footnote-126 "An alternative token ([lex.digraph]) is not an identifier, even when its spelling consists entirely of letters and underscores. Therefore it is not possible to define a macro whose name is the same as that of an alternative token.")
The replacement list is then rescanned for more macro names as
specified below[.](#general-11.sentence-2)
[12](#general-12)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L1574)
[*Example [2](#general-example-2)*:
The simplest use of this facility is to define a “manifest constant”,
as in#define TABSIZE 100int table[TABSIZE];
— *end example*]
[13](#general-13)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L1584)
A preprocessing directive of the form
# define [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]") [*lparen*](cpp.pre#nt:lparen "15.1Preamble[cpp.pre]") [*identifier-list*](cpp.pre#nt:identifier-list "15.1Preamble[cpp.pre]")opt ) [*replacement-list*](cpp.pre#nt:replacement-list "15.1Preamble[cpp.pre]") [*new-line*](cpp.pre#nt:new-line "15.1Preamble[cpp.pre]")
# define [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]") [*lparen*](cpp.pre#nt:lparen "15.1Preamble[cpp.pre]") ... ) [*replacement-list*](cpp.pre#nt:replacement-list "15.1Preamble[cpp.pre]") [*new-line*](cpp.pre#nt:new-line "15.1Preamble[cpp.pre]")
# define [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]") [*lparen*](cpp.pre#nt:lparen "15.1Preamble[cpp.pre]") [*identifier-list*](cpp.pre#nt:identifier-list "15.1Preamble[cpp.pre]") , ... ) [*replacement-list*](cpp.pre#nt:replacement-list "15.1Preamble[cpp.pre]") [*new-line*](cpp.pre#nt:new-line "15.1Preamble[cpp.pre]")
defines a [*function-like macro*](#def:macro,function-like "15.7.1General[cpp.replace.general]") with parameters, whose use is
similar syntactically to a function call[.](#general-13.sentence-1)
The parametersare specified by the optional list of identifiers[.](#general-13.sentence-2)
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)[.](#general-13.sentence-3)
The replaced sequence of preprocessing tokens is terminated by the matching) preprocessing token, skipping intervening matched pairs of left and
right parenthesis preprocessing tokens[.](#general-13.sentence-4)
Within the sequence of preprocessing tokens making up an invocation
of a function-like macro,
new-line is considered a normal whitespace character[.](#general-13.sentence-5)
[14](#general-14)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L1612)
The sequence of preprocessing tokens
bounded by the outside-most matching parentheses
forms the list of arguments for the function-like macro[.](#general-14.sentence-1)
The individual arguments within the list
are separated by comma preprocessing tokens,
but comma preprocessing tokens between matching
inner parentheses do not separate arguments[.](#general-14.sentence-2)
If there are sequences of preprocessing tokens within the list of
arguments that would otherwise act as preprocessing directives,[127](#footnote-127 "A conditionally-supported-directive is a preprocessing directive regardless of whether the implementation supports it.") the program is ill-formed[.](#general-14.sentence-3)
[15](#general-15)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L1628)
[*Example [3](#general-example-3)*:
The following defines a function-like
macro whose value is the maximum of its arguments[.](#general-15.sentence-1)
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[.](#general-15.sentence-2)
It also cannot have its address taken,
as it has none[.](#general-15.sentence-3)
#define max(a, b) ((a) > (b) ? (a) : (b))
The parentheses ensure that the arguments and
the resulting expression are bound properly[.](#general-15.sentence-4)
— *end example*]
[16](#general-16)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L1649)
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*](#def:variable_arguments "15.7.1General[cpp.replace.general]")[.](#general-16.sentence-1)
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...)[.](#general-16.sentence-2)
[125)](#footnote-125)[125)](#footnoteref-125)
Since, by macro-replacement time,
all [*character-literal*](lex.ccon#nt:character-literal "5.13.3Character literals[lex.ccon]")*s* and [*string-literal*](lex.string#nt:string-literal "5.13.5String literals[lex.string]")*s* are preprocessing tokens,
not sequences possibly containing identifier-like subsequences
(see [[lex.phases]](lex.phases "5.2Phases of translation"), translation phases),
they are never scanned for macro names or parameters[.](#footnote-125.sentence-1)
[126)](#footnote-126)[126)](#footnoteref-126)
An alternative token ([[lex.digraph]](lex.digraph "5.9Alternative tokens")) is not an identifier,
even when its spelling consists entirely of letters and underscores[.](#footnote-126.sentence-1)
Therefore it is not possible to define a macro
whose name is the same as that of an alternative token[.](#footnote-126.sentence-2)
[127)](#footnote-127)[127)](#footnoteref-127)
A [*conditionally-supported-directive*](cpp.pre#nt:conditionally-supported-directive "15.1Preamble[cpp.pre]") is a preprocessing directive regardless of whether the implementation supports it[.](#footnote-127.sentence-1)
### [15.7.2](#cpp.subst) Argument substitution [[cpp.subst]](cpp.subst)
[va-opt-replacement:](#nt:va-opt-replacement "15.7.2Argument substitution[cpp.subst]")
__VA_OPT__ ( [*pp-tokens*](cpp.pre#nt:pp-tokens "15.1Preamble[cpp.pre]")opt )
[1](#cpp.subst-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L1670)
After the arguments for the invocation of a function-like macro have
been identified, argument substitution takes place[.](#cpp.subst-1.sentence-1)
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:
- [(1.1)](#cpp.subst-1.1)
If the parameter is of the form [*va-opt-replacement*](#nt:va-opt-replacement "15.7.2Argument substitution[cpp.subst]"),
the replacement preprocessing tokens are the
preprocessing token sequence for the corresponding argument,
as specified below[.](#cpp.subst-1.1.sentence-1)
- [(1.2)](#cpp.subst-1.2)
Otherwise, the replacement preprocessing tokens are the
preprocessing tokens of corresponding argument after all
macros contained therein have been expanded[.](#cpp.subst-1.2.sentence-1)
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[.](#cpp.subst-1.2.sentence-2)
[*Example [1](#cpp.subst-example-1)*: #define LPAREN() (#define G(Q) 42#define F(R, X, ...) __VA_OPT__(G R X) )int x = F(LPAREN(), 0, <:-); // replaced by int x = 42; — *end example*]
[2](#cpp.subst-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L1700)
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[.](#cpp.subst-2.sentence-1)
[3](#cpp.subst-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L1706)
[*Example [2](#cpp.subst-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*]
[4](#cpp.subst-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L1726)
The identifier __VA_OPT__ shall always occur as part of the preprocessing token sequence[*va-opt-replacement*](#nt:va-opt-replacement "15.7.2Argument substitution[cpp.subst]");
its closing ) is determined by skipping
intervening pairs of matching left and right parentheses
in its [*pp-tokens*](cpp.pre#nt:pp-tokens "15.1Preamble[cpp.pre]")[.](#cpp.subst-4.sentence-1)
The [*pp-tokens*](cpp.pre#nt:pp-tokens "15.1Preamble[cpp.pre]") of a [*va-opt-replacement*](#nt:va-opt-replacement "15.7.2Argument substitution[cpp.subst]") shall not contain __VA_OPT__[.](#cpp.subst-4.sentence-2)
If the [*pp-tokens*](cpp.pre#nt:pp-tokens "15.1Preamble[cpp.pre]") would be ill-formed
as the replacement list of the current function-like macro,
the program is ill-formed[.](#cpp.subst-4.sentence-3)
A [*va-opt-replacement*](#nt:va-opt-replacement "15.7.2Argument substitution[cpp.subst]") is treated as if it were a parameter,
and the preprocessing token sequence for the corresponding
argument is defined as follows[.](#cpp.subst-4.sentence-4)
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.concat "15.7.4The ## operator"), [[cpp.rescan]](#cpp.rescan "15.7.5Rescanning and further replacement"))[.](#cpp.subst-4.sentence-5)
Otherwise, the argument consists of
the results of the expansion of the contained [*pp-tokens*](cpp.pre#nt:pp-tokens "15.1Preamble[cpp.pre]") as the replacement list of the current function-like macro
before removal of placemarker tokens, rescanning, and further replacement[.](#cpp.subst-4.sentence-6)
[*Note [1](#cpp.subst-note-1)*:
The placemarker tokens are removed before stringization ([[cpp.stringize]](#cpp.stringize "15.7.3The # operator")),
and can be removed by rescanning and further replacement ([[cpp.rescan]](#cpp.rescan "15.7.5Rescanning and further replacement"))[.](#cpp.subst-4.sentence-7)
— *end note*]
[*Example [3](#cpp.subst-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) // replaced by f(0, a, b, c) F() // replaced by f(0) F(EMP) // replaced by f(0) 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) SDEF(foo); // replaced by S foo; SDEF(bar, 1, 2); // replaced by S bar = { 1, 2 };#define H1(X, ...) X __VA_OPT__(##) __VA_ARGS__ // error: ## may not appear at// the beginning of a replacement list ([[cpp.concat]](#cpp.concat "15.7.4The ## operator"))#define H2(X, Y, ...) __VA_OPT__(X ## Y,) __VA_ARGS__
H2(a, b, c, d) // replaced by ab, c, d#define H3(X, ...) #__VA_OPT__(X##X X##X) H3(, 0) // replaced by ""#define H4(X, ...) __VA_OPT__(a X ## X) ## b
H4(, 1) // replaced by a b#define H5A(...) __VA_OPT__()/**/__VA_OPT__()#define H5B(X) a ## X ## b#define H5C(X) H5B(X) H5C(H5A()) // replaced by ab — *end example*]
### [15.7.3](#cpp.stringize) The # operator [[cpp.stringize]](cpp.stringize)
[1](#cpp.stringize-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L1795)
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[.](#cpp.stringize-1.sentence-1)
[2](#cpp.stringize-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L1802)
A [*character string literal*](#def:character_string_literal "15.7.3The # operator[cpp.stringize]") is a [*string-literal*](lex.string#nt:string-literal "5.13.5String literals[lex.string]") with no prefix[.](#cpp.stringize-2.sentence-1)
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)[.](#cpp.stringize-2.sentence-2)
Let the [*stringizing argument*](#def:stringizing_argument "15.7.3The # operator[cpp.stringize]") be the preprocessing token sequence
for the corresponding argument with placemarker tokens removed[.](#cpp.stringize-2.sentence-3)
Each occurrence of whitespace between the stringizing argument's preprocessing
tokens becomes a single space character in the character string literal[.](#cpp.stringize-2.sentence-4)
Whitespace before the first preprocessing token and after the last
preprocessing token comprising the stringizing argument is deleted[.](#cpp.stringize-2.sentence-5)
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 of[*header-name*](lex.header#nt:header-name "5.6Header names[lex.header]")*s*,[*character-literal*](lex.ccon#nt:character-literal "5.13.3Character literals[lex.ccon]")*s*,
and [*string-literal*](lex.string#nt:string-literal "5.13.5String literals[lex.string]")*s* (including the delimiting U+0022 quotation mark ("))
contained within the preprocessing token:
a U+005c reverse solidus character (\)
is inserted before each U+0022 quotation mark andU+005c reverse solidus character of a[*header-name*](lex.header#nt:header-name "5.6Header names[lex.header]"),[*character-literal*](lex.ccon#nt:character-literal "5.13.3Character literals[lex.ccon]"),
or [*string-literal*](lex.string#nt:string-literal "5.13.5String literals[lex.string]"),
and each new-line character is
replaced by the two-character sequence \n[.](#cpp.stringize-2.sentence-6)
If the replacement that results is not a valid character string literal,
the program is ill-formed[.](#cpp.stringize-2.sentence-7)
The character string literal corresponding to
an empty stringizing argument is ""[.](#cpp.stringize-2.sentence-8)
The order of evaluation of# and## operators is unspecified[.](#cpp.stringize-2.sentence-9)
### [15.7.4](#cpp.concat) The ## operator [[cpp.concat]](cpp.concat)
[1](#cpp.concat-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L1847)
A## preprocessing token shall not occur at the beginning or
at the end of a replacement list for either form
of macro definition[.](#cpp.concat-1.sentence-1)
[2](#cpp.concat-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L1854)
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[.](#cpp.concat-2.sentence-1)[128](#footnote-128 "Placemarker preprocessing tokens do not appear in the syntax because they are temporary entities that exist only within translation phase 4.")
[3](#cpp.concat-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L1866)
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[.](#cpp.concat-3.sentence-1)
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[.](#cpp.concat-3.sentence-2)
[*Note [1](#cpp.concat-note-1)*:
Concatenation can form
a [*universal-character-name*](lex.universal.char#nt:universal-character-name "5.3.2Universal character names[lex.universal.char]") ([[lex.charset]](lex.charset "5.3.1Character sets"))[.](#cpp.concat-3.sentence-3)
— *end note*]
If the result is not a valid preprocessing token,
the program is ill-formed[.](#cpp.concat-3.sentence-4)
The resulting preprocessing token is available for further macro replacement[.](#cpp.concat-3.sentence-5)
The order of evaluation of## operators is unspecified[.](#cpp.concat-3.sentence-6)
[4](#cpp.concat-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L1890)
[*Example [1](#cpp.concat-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') // this goes away== 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[.](#cpp.concat-4.sentence-2)
— *end example*]
[5](#cpp.concat-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L1932)
[*Example [2](#cpp.concat-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); // equivalent to char p[] = "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[.](#cpp.concat-5.sentence-3)
— *end example*]
[6](#cpp.concat-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L1957)
[*Example [3](#cpp.concat-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*]
[128)](#footnote-128)[128)](#footnoteref-128)
Placemarker preprocessing tokens do not appear in the syntax
because they are temporary entities that exist only within translation phase 4[.](#footnote-128.sentence-1)
### [15.7.5](#cpp.rescan) Rescanning and further replacement [[cpp.rescan]](cpp.rescan)
[1](#cpp.rescan-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L1976)
After all parameters in the replacement list have been substituted and # and ## processing has taken
place, all placemarker preprocessing tokens are removed[.](#cpp.rescan-1.sentence-1)
Then
the resulting preprocessing token sequence is rescanned, along with all
subsequent preprocessing tokens of the source file, for more macro names
to replace[.](#cpp.rescan-1.sentence-2)
[2](#cpp.rescan-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L1983)
[*Example [1](#cpp.rescan-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*]
[3](#cpp.rescan-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L2017)
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[.](#cpp.rescan-3.sentence-1)
Furthermore,
if any nested replacements encounter the name of the macro being replaced,
it is not replaced[.](#cpp.rescan-3.sentence-2)
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[.](#cpp.rescan-3.sentence-3)
[4](#cpp.rescan-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L2030)
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]](cpp.pragma.op "15.13Pragma operator") below[.](#cpp.rescan-4.sentence-1)
### [15.7.6](#cpp.scope) Scope of macro definitions [[cpp.scope]](cpp.scope)
[1](#cpp.scope-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L2040)
A macro definition lasts
(independent of block structure)
until a corresponding#undef directive is encountered or
(if none is encountered)
until the end of the translation unit[.](#cpp.scope-1.sentence-1)
Macro definitions have no significance after translation phase 4[.](#cpp.scope-1.sentence-2)
[2](#cpp.scope-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L2050)
A preprocessing directive of the form
# undef [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]") [*new-line*](cpp.pre#nt:new-line "15.1Preamble[cpp.pre]")
causes the specified identifier no longer to be defined as a macro name[.](#cpp.scope-2.sentence-1)
It is ignored if the specified identifier is not currently defined as
a macro name[.](#cpp.scope-2.sentence-2)

View File

@@ -0,0 +1,240 @@
[cpp.replace.general]
# 15 Preprocessing directives [[cpp]](./#cpp)
## 15.7 Macro replacement [[cpp.replace]](cpp.replace#general)
### 15.7.1 General [cpp.replace.general]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L1443)
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[.](#1.sentence-1)
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L1450)
An identifier currently defined as anobject-like macro (see below) may be redefined by another#define preprocessing 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[.](#2.sentence-1)
Likewise, an identifier currently defined as afunction-like macro (see below) may be redefined by another#define preprocessing 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[.](#2.sentence-2)
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L1468)
[*Example [1](#example-1)*:
The following sequence is valid:#define OBJ_LIKE (1-1)#define OBJ_LIKE /* whitespace */ (1-1) /* other */#define FUNC_LIKE(a) ( a )#define FUNC_LIKE( a )( /* note the whitespace */ \
a /* other stuff on this line
*/ )
But the following redefinitions are invalid:#define OBJ_LIKE (0) // different token sequence#define OBJ_LIKE (1 - 1) // different whitespace#define FUNC_LIKE(b) ( a ) // different parameter usage#define FUNC_LIKE(b) ( b ) // different parameter spelling
— *end example*]
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L1488)
There shall be whitespace between the identifier and the replacement list
in the definition of an object-like macro[.](#4.sentence-1)
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L1493)
If the [*identifier-list*](cpp.pre#nt:identifier-list "15.1Preamble[cpp.pre]") 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[.](#5.sentence-1)
Otherwise, there shall be at least as many arguments in the invocation as there are
parameters in the macro definition (excluding the ...)[.](#5.sentence-2)
There
shall exist a) preprocessing token that terminates the invocation[.](#5.sentence-3)
[6](#6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L1505)
The identifiers __VA_ARGS__ and __VA_OPT__ shall occur only in the [*replacement-list*](cpp.pre#nt:replacement-list "15.1Preamble[cpp.pre]") of a function-like macro that uses the ellipsis notation in the parameters[.](#6.sentence-1)
[7](#7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L1512)
A parameter identifier in a function-like macro
shall be uniquely declared within its scope[.](#7.sentence-1)
[8](#8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L1516)
The identifier immediately following thedefine is called the[*macro name*](#def:macro,name "15.7.1General[cpp.replace.general]")[.](#8.sentence-1)
There is one name space for macro names[.](#8.sentence-2)
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[.](#8.sentence-3)
[9](#9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L1527)
A translation unit shall not #define or #undef names lexically identical
to keywords,
to the identifiers listed in Table [4](lex.name#tab:lex.name.special "Table 4: Identifiers with special meaning"), or
to the [*attribute-token*](dcl.attr.grammar#nt:attribute-token "9.13.1Attribute syntax and semantics[dcl.attr.grammar]")*s* described in [[dcl.attr]](dcl.attr "9.13Attributes"),
except that the names likely and unlikely may be
defined as function-like macros[.](#9.sentence-1)
[10](#10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L1537)
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[.](#10.sentence-1)
[11](#11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L1547)
A preprocessing directive of the form
# define [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]") [*replacement-list*](cpp.pre#nt:replacement-list "15.1Preamble[cpp.pre]") [*new-line*](cpp.pre#nt:new-line "15.1Preamble[cpp.pre]")
defines an[*object-like macro*](#def:macro,object-like "15.7.1General[cpp.replace.general]") that
causes each subsequent instance of the macro name[125](#footnote-125 "Since, by macro-replacement time, all character-literals and string-literals are preprocessing tokens, not sequences possibly containing identifier-like subsequences (see [lex.phases], translation phases), they are never scanned for macro names or parameters.") to be replaced by the replacement list of preprocessing tokens
that constitute the remainder of the directive[.](#11.sentence-1)[126](#footnote-126 "An alternative token ([lex.digraph]) is not an identifier, even when its spelling consists entirely of letters and underscores. Therefore it is not possible to define a macro whose name is the same as that of an alternative token.")
The replacement list is then rescanned for more macro names as
specified below[.](#11.sentence-2)
[12](#12)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L1574)
[*Example [2](#example-2)*:
The simplest use of this facility is to define a “manifest constant”,
as in#define TABSIZE 100int table[TABSIZE];
— *end example*]
[13](#13)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L1584)
A preprocessing directive of the form
# define [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]") [*lparen*](cpp.pre#nt:lparen "15.1Preamble[cpp.pre]") [*identifier-list*](cpp.pre#nt:identifier-list "15.1Preamble[cpp.pre]")opt ) [*replacement-list*](cpp.pre#nt:replacement-list "15.1Preamble[cpp.pre]") [*new-line*](cpp.pre#nt:new-line "15.1Preamble[cpp.pre]")
# define [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]") [*lparen*](cpp.pre#nt:lparen "15.1Preamble[cpp.pre]") ... ) [*replacement-list*](cpp.pre#nt:replacement-list "15.1Preamble[cpp.pre]") [*new-line*](cpp.pre#nt:new-line "15.1Preamble[cpp.pre]")
# define [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]") [*lparen*](cpp.pre#nt:lparen "15.1Preamble[cpp.pre]") [*identifier-list*](cpp.pre#nt:identifier-list "15.1Preamble[cpp.pre]") , ... ) [*replacement-list*](cpp.pre#nt:replacement-list "15.1Preamble[cpp.pre]") [*new-line*](cpp.pre#nt:new-line "15.1Preamble[cpp.pre]")
defines a [*function-like macro*](#def:macro,function-like "15.7.1General[cpp.replace.general]") with parameters, whose use is
similar syntactically to a function call[.](#13.sentence-1)
The parametersare specified by the optional list of identifiers[.](#13.sentence-2)
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)[.](#13.sentence-3)
The replaced sequence of preprocessing tokens is terminated by the matching) preprocessing token, skipping intervening matched pairs of left and
right parenthesis preprocessing tokens[.](#13.sentence-4)
Within the sequence of preprocessing tokens making up an invocation
of a function-like macro,
new-line is considered a normal whitespace character[.](#13.sentence-5)
[14](#14)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L1612)
The sequence of preprocessing tokens
bounded by the outside-most matching parentheses
forms the list of arguments for the function-like macro[.](#14.sentence-1)
The individual arguments within the list
are separated by comma preprocessing tokens,
but comma preprocessing tokens between matching
inner parentheses do not separate arguments[.](#14.sentence-2)
If there are sequences of preprocessing tokens within the list of
arguments that would otherwise act as preprocessing directives,[127](#footnote-127 "A conditionally-supported-directive is a preprocessing directive regardless of whether the implementation supports it.") the program is ill-formed[.](#14.sentence-3)
[15](#15)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L1628)
[*Example [3](#example-3)*:
The following defines a function-like
macro whose value is the maximum of its arguments[.](#15.sentence-1)
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[.](#15.sentence-2)
It also cannot have its address taken,
as it has none[.](#15.sentence-3)
#define max(a, b) ((a) > (b) ? (a) : (b))
The parentheses ensure that the arguments and
the resulting expression are bound properly[.](#15.sentence-4)
— *end example*]
[16](#16)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L1649)
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*](#def:variable_arguments "15.7.1General[cpp.replace.general]")[.](#16.sentence-1)
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...)[.](#16.sentence-2)
[125)](#footnote-125)[125)](#footnoteref-125)
Since, by macro-replacement time,
all [*character-literal*](lex.ccon#nt:character-literal "5.13.3Character literals[lex.ccon]")*s* and [*string-literal*](lex.string#nt:string-literal "5.13.5String literals[lex.string]")*s* are preprocessing tokens,
not sequences possibly containing identifier-like subsequences
(see [[lex.phases]](lex.phases "5.2Phases of translation"), translation phases),
they are never scanned for macro names or parameters[.](#footnote-125.sentence-1)
[126)](#footnote-126)[126)](#footnoteref-126)
An alternative token ([[lex.digraph]](lex.digraph "5.9Alternative tokens")) is not an identifier,
even when its spelling consists entirely of letters and underscores[.](#footnote-126.sentence-1)
Therefore it is not possible to define a macro
whose name is the same as that of an alternative token[.](#footnote-126.sentence-2)
[127)](#footnote-127)[127)](#footnoteref-127)
A [*conditionally-supported-directive*](cpp.pre#nt:conditionally-supported-directive "15.1Preamble[cpp.pre]") is a preprocessing directive regardless of whether the implementation supports it[.](#footnote-127.sentence-1)

61
cppdraft/cpp/rescan.md Normal file
View File

@@ -0,0 +1,61 @@
[cpp.rescan]
# 15 Preprocessing directives [[cpp]](./#cpp)
## 15.7 Macro replacement [[cpp.replace]](cpp.replace#cpp.rescan)
### 15.7.5 Rescanning and further replacement [cpp.rescan]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L1976)
After all parameters in the replacement list have been substituted and # and ## processing has taken
place, all placemarker preprocessing tokens are removed[.](#1.sentence-1)
Then
the resulting preprocessing token sequence is rescanned, along with all
subsequent preprocessing tokens of the source file, for more macro names
to replace[.](#1.sentence-2)
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L1983)
[*Example [1](#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*]
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L2017)
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[.](#3.sentence-1)
Furthermore,
if any nested replacements encounter the name of the macro being replaced,
it is not replaced[.](#3.sentence-2)
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[.](#3.sentence-3)
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L2030)
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]](cpp.pragma.op "15.13Pragma operator") below[.](#4.sentence-1)

32
cppdraft/cpp/scope.md Normal file
View File

@@ -0,0 +1,32 @@
[cpp.scope]
# 15 Preprocessing directives [[cpp]](./#cpp)
## 15.7 Macro replacement [[cpp.replace]](cpp.replace#cpp.scope)
### 15.7.6 Scope of macro definitions [cpp.scope]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L2040)
A macro definition lasts
(independent of block structure)
until a corresponding#undef directive is encountered or
(if none is encountered)
until the end of the translation unit[.](#1.sentence-1)
Macro definitions have no significance after translation phase 4[.](#1.sentence-2)
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L2050)
A preprocessing directive of the form
# undef [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]") [*new-line*](cpp.pre#nt:new-line "15.1Preamble[cpp.pre]")
causes the specified identifier no longer to be defined as a macro name[.](#2.sentence-1)
It is ignored if the specified identifier is not currently defined as
a macro name[.](#2.sentence-2)

55
cppdraft/cpp/stringize.md Normal file
View File

@@ -0,0 +1,55 @@
[cpp.stringize]
# 15 Preprocessing directives [[cpp]](./#cpp)
## 15.7 Macro replacement [[cpp.replace]](cpp.replace#cpp.stringize)
### 15.7.3 The # operator [cpp.stringize]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L1795)
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[.](#1.sentence-1)
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L1802)
A [*character string literal*](#def:character_string_literal "15.7.3The # operator[cpp.stringize]") is a [*string-literal*](lex.string#nt:string-literal "5.13.5String literals[lex.string]") with no prefix[.](#2.sentence-1)
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)[.](#2.sentence-2)
Let the [*stringizing argument*](#def:stringizing_argument "15.7.3The # operator[cpp.stringize]") be the preprocessing token sequence
for the corresponding argument with placemarker tokens removed[.](#2.sentence-3)
Each occurrence of whitespace between the stringizing argument's preprocessing
tokens becomes a single space character in the character string literal[.](#2.sentence-4)
Whitespace before the first preprocessing token and after the last
preprocessing token comprising the stringizing argument is deleted[.](#2.sentence-5)
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 of[*header-name*](lex.header#nt:header-name "5.6Header names[lex.header]")*s*,[*character-literal*](lex.ccon#nt:character-literal "5.13.3Character literals[lex.ccon]")*s*,
and [*string-literal*](lex.string#nt:string-literal "5.13.5String literals[lex.string]")*s* (including the delimiting U+0022 quotation mark ("))
contained within the preprocessing token:
a U+005c reverse solidus character (\)
is inserted before each U+0022 quotation mark andU+005c reverse solidus character of a[*header-name*](lex.header#nt:header-name "5.6Header names[lex.header]"),[*character-literal*](lex.ccon#nt:character-literal "5.13.3Character literals[lex.ccon]"),
or [*string-literal*](lex.string#nt:string-literal "5.13.5String literals[lex.string]"),
and each new-line character is
replaced by the two-character sequence \n[.](#2.sentence-6)
If the replacement that results is not a valid character string literal,
the program is ill-formed[.](#2.sentence-7)
The character string literal corresponding to
an empty stringizing argument is ""[.](#2.sentence-8)
The order of evaluation of# and## operators is unspecified[.](#2.sentence-9)

105
cppdraft/cpp/subst.md Normal file
View File

@@ -0,0 +1,105 @@
[cpp.subst]
# 15 Preprocessing directives [[cpp]](./#cpp)
## 15.7 Macro replacement [[cpp.replace]](cpp.replace#cpp.subst)
### 15.7.2 Argument substitution [cpp.subst]
[va-opt-replacement:](#nt:va-opt-replacement "15.7.2Argument substitution[cpp.subst]")
__VA_OPT__ ( [*pp-tokens*](cpp.pre#nt:pp-tokens "15.1Preamble[cpp.pre]")opt )
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L1670)
After the arguments for the invocation of a function-like macro have
been identified, argument substitution takes place[.](#1.sentence-1)
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:
- [(1.1)](#1.1)
If the parameter is of the form [*va-opt-replacement*](#nt:va-opt-replacement "15.7.2Argument substitution[cpp.subst]"),
the replacement preprocessing tokens are the
preprocessing token sequence for the corresponding argument,
as specified below[.](#1.1.sentence-1)
- [(1.2)](#1.2)
Otherwise, the replacement preprocessing tokens are the
preprocessing tokens of corresponding argument after all
macros contained therein have been expanded[.](#1.2.sentence-1)
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[.](#1.2.sentence-2)
[*Example [1](#example-1)*: #define LPAREN() (#define G(Q) 42#define F(R, X, ...) __VA_OPT__(G R X) )int x = F(LPAREN(), 0, <:-); // replaced by int x = 42; — *end example*]
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L1700)
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[.](#2.sentence-1)
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L1706)
[*Example [2](#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*]
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/preprocessor.tex#L1726)
The identifier __VA_OPT__ shall always occur as part of the preprocessing token sequence[*va-opt-replacement*](#nt:va-opt-replacement "15.7.2Argument substitution[cpp.subst]");
its closing ) is determined by skipping
intervening pairs of matching left and right parentheses
in its [*pp-tokens*](cpp.pre#nt:pp-tokens "15.1Preamble[cpp.pre]")[.](#4.sentence-1)
The [*pp-tokens*](cpp.pre#nt:pp-tokens "15.1Preamble[cpp.pre]") of a [*va-opt-replacement*](#nt:va-opt-replacement "15.7.2Argument substitution[cpp.subst]") shall not contain __VA_OPT__[.](#4.sentence-2)
If the [*pp-tokens*](cpp.pre#nt:pp-tokens "15.1Preamble[cpp.pre]") would be ill-formed
as the replacement list of the current function-like macro,
the program is ill-formed[.](#4.sentence-3)
A [*va-opt-replacement*](#nt:va-opt-replacement "15.7.2Argument substitution[cpp.subst]") is treated as if it were a parameter,
and the preprocessing token sequence for the corresponding
argument is defined as follows[.](#4.sentence-4)
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.concat "15.7.4The ## operator"), [[cpp.rescan]](cpp.rescan "15.7.5Rescanning and further replacement"))[.](#4.sentence-5)
Otherwise, the argument consists of
the results of the expansion of the contained [*pp-tokens*](cpp.pre#nt:pp-tokens "15.1Preamble[cpp.pre]") as the replacement list of the current function-like macro
before removal of placemarker tokens, rescanning, and further replacement[.](#4.sentence-6)
[*Note [1](#note-1)*:
The placemarker tokens are removed before stringization ([[cpp.stringize]](cpp.stringize "15.7.3The # operator")),
and can be removed by rescanning and further replacement ([[cpp.rescan]](cpp.rescan "15.7.5Rescanning and further replacement"))[.](#4.sentence-7)
— *end note*]
[*Example [3](#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) // replaced by f(0, a, b, c) F() // replaced by f(0) F(EMP) // replaced by f(0) 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) SDEF(foo); // replaced by S foo; SDEF(bar, 1, 2); // replaced by S bar = { 1, 2 };#define H1(X, ...) X __VA_OPT__(##) __VA_ARGS__ // error: ## may not appear at// the beginning of a replacement list ([[cpp.concat]](cpp.concat "15.7.4The ## operator"))#define H2(X, Y, ...) __VA_OPT__(X ## Y,) __VA_ARGS__
H2(a, b, c, d) // replaced by ab, c, d#define H3(X, ...) #__VA_OPT__(X##X X##X) H3(, 0) // replaced by ""#define H4(X, ...) __VA_OPT__(a X ## X) ## b
H4(, 1) // replaced by a b#define H5A(...) __VA_OPT__()/**/__VA_OPT__()#define H5B(X) a ## X ## b#define H5C(X) H5B(X) H5C(H5A()) // replaced by ab — *end example*]