From Jason Turner

[cpp.cond]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmppzu_wezh/{from.md → to.md} +74 -44
tmp/tmppzu_wezh/{from.md → to.md} RENAMED
@@ -11,12 +11,11 @@ h-preprocessing-token:
11
  any *preprocessing-token* other than '>'
12
  ```
13
 
14
  ``` bnf
15
  h-pp-tokens:
16
- h-preprocessing-token
17
- h-pp-tokens h-preprocessing-token
18
  ```
19
 
20
  ``` bnf
21
  header-name-tokens:
22
  string-literal
@@ -27,79 +26,104 @@ header-name-tokens:
27
  has-include-expression:
28
  '__has_include' '(' header-name ')'
29
  '__has_include' '(' header-name-tokens ')'
30
  ```
31
 
 
 
 
 
 
 
32
  ``` bnf
33
  has-attribute-expression:
34
  '__has_cpp_attribute (' pp-tokens ')'
35
  ```
36
 
37
  The expression that controls conditional inclusion shall be an integral
38
  constant expression except that identifiers (including those lexically
39
  identical to keywords) are interpreted as described below[^2]
40
 
41
- and it may contain zero or more *defined-macro-expression*s and/or
42
- *has-include-expression*s and/or *has-attribute-expression*s as unary
43
- operator expressions.
 
 
44
 
45
  A *defined-macro-expression* evaluates to `1` if the identifier is
46
  currently defined as a macro name (that is, if it is predefined or if it
47
  has one or more active macro definitions [[cpp.import]], for example
48
  because it has been the subject of a `#define` preprocessing directive
49
  without an intervening `#undef` directive with the same subject
50
  identifier), `0` if it is not.
51
 
52
- The second form of *has-include-expression* is considered only if the
53
- first form does not match, in which case the preprocessing tokens are
54
- processed just as in normal text.
55
-
56
  The header or source file identified by the parenthesized preprocessing
57
  token sequence in each contained *has-include-expression* is searched
58
- for as if that preprocessing token sequence were the *pp-tokens* in a
59
  `#include` directive, except that no further macro expansion is
60
- performed. If such a directive would not satisfy the syntactic
61
- requirements of a `#include` directive, the program is ill-formed. The
 
62
  *has-include-expression* evaluates to `1` if the search for the source
63
  file succeeds, and to `0` if the search fails.
64
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
65
  Each *has-attribute-expression* is replaced by a non-zero *pp-number*
66
  matching the form of an *integer-literal* if the implementation supports
67
  an attribute with the name specified by interpreting the *pp-tokens*,
68
  after macro expansion, as an *attribute-token*, and by `0` otherwise.
69
  The program is ill-formed if the *pp-tokens* do not match the form of an
70
  *attribute-token*.
71
 
72
- For an attribute specified in this document, the value of the
73
- *has-attribute-expression* is given by [[cpp.cond.ha]]. For other
74
- attributes recognized by the implementation, the value is
 
75
  *implementation-defined*.
76
 
77
- [*Note 1*: It is expected that the availability of an attribute can be
78
  detected by any non-zero result. — *end note*]
79
 
80
  **Table: __has_cpp_attribute values** <a id="cpp.cond.ha">[cpp.cond.ha]</a>
81
 
82
  | Attribute | Value |
83
- | -------------------- | --------- |
84
  | `assume` | `202207L` |
85
- | `carries_dependency` | `200809L` |
86
  | `deprecated` | `201309L` |
87
  | `fallthrough` | `201603L` |
 
88
  | `likely` | `201803L` |
89
  | `maybe_unused` | `201603L` |
90
  | `no_unique_address` | `201803L` |
91
  | `nodiscard` | `201907L` |
92
  | `noreturn` | `200809L` |
93
  | `unlikely` | `201803L` |
94
 
95
 
96
  The `#ifdef`, `#ifndef`, `#elifdef`, and `#elifndef` directives, and the
97
- `defined` conditional inclusion operator, shall treat `__has_include`
98
- and `__has_cpp_attribute` as if they were the names of defined macros.
99
- The identifiers `__has_include` and `__has_cpp_attribute` shall not
100
- appear in any context not mentioned in this subclause.
 
101
 
102
  Each preprocessing token that remains (in the list of preprocessing
103
  tokens that will become the controlling expression) after all macro
104
  replacements have occurred shall be in the lexical form of a token
105
  [[lex.token]].
@@ -114,44 +138,50 @@ Preprocessing directives of the forms
114
  check whether the controlling constant expression evaluates to nonzero.
115
 
116
  Prior to evaluation, macro invocations in the list of preprocessing
117
  tokens that will become the controlling constant expression are replaced
118
  (except for those macro names modified by the `defined` unary operator),
119
- just as in normal text. If the token `defined` is generated as a result
120
- of this replacement process or use of the `defined` unary operator does
121
- not match one of the two specified forms prior to macro replacement, the
122
- behavior is undefined.
 
 
 
 
 
 
123
 
124
  After all replacements due to macro expansion and evaluations of
125
- *defined-macro-expression*s, *has-include-expression*s, and
126
- *has-attribute-expression*s have been performed, all remaining
127
- identifiers and keywords, except for `true` and `false`, are replaced
128
- with the *pp-number* `0`, and then each preprocessing token is converted
129
- into a token.
130
 
131
- [*Note 2*: An alternative token [[lex.digraph]] is not an identifier,
132
  even when its spelling consists entirely of letters and underscores.
133
  Therefore it is not subject to this replacement. — *end note*]
134
 
135
  The resulting tokens comprise the controlling constant expression which
136
  is evaluated according to the rules of  [[expr.const]] using arithmetic
137
  that has at least the ranges specified in  [[support.limits]]. For the
138
  purposes of this token conversion and evaluation all signed and unsigned
139
  integer types act as if they have the same representation as,
140
  respectively, `intmax_t` or `uintmax_t` [[cstdint.syn]].
141
 
142
- [*Note 3*: Thus on an implementation where
143
  `std::numeric_limits<int>::max()` is `0x7FFF` and
144
  `std::numeric_limits<unsigned int>::max()` is `0xFFFF`, the integer
145
  literal `0x8000` is signed and positive within a `#if` expression even
146
  though it is unsigned in translation phase 7
147
  [[lex.phases]]. — *end note*]
148
 
149
  This includes interpreting *character-literal*s according to the rules
150
  in [[lex.ccon]].
151
 
152
- [*Note 4*: The associated character encodings of literals are the same
153
  in `#if` and `#elif` directives and in any expression. — *end note*]
154
 
155
  Each subexpression with type `bool` is subjected to integral promotion
156
  before processing continues.
157
 
@@ -169,20 +199,20 @@ name. Their conditions are equivalent to `#if` `defined` *identifier*,
169
  `#if` `!defined` *identifier*, `#elif` `defined` *identifier*, and
170
  `#elif` `!defined` *identifier*, respectively.
171
 
172
  Each directive’s condition is checked in order. If it evaluates to false
173
  (zero), the group that it controls is skipped: directives are processed
174
- only through the name that determines the directive in order to keep
175
- track of the level of nested conditionals; the rest of the directives’
176
- preprocessing tokens are ignored, as are the other preprocessing tokens
177
- in the group. Only the first group whose control condition evaluates to
178
- true (nonzero) is processed; any following groups are skipped and their
179
- controlling directives are processed as if they were in a group that is
180
- skipped. If none of the conditions evaluates to true, and there is a
181
- `#else` directive, the group controlled by the `#else` is processed;
182
- lacking a `#else` directive, all the groups until the `#endif` are
183
- skipped.[^3]
184
 
185
  [*Example 1*:
186
 
187
  This demonstrates a way to include a library `optional` facility only if
188
  it is available:
 
11
  any *preprocessing-token* other than '>'
12
  ```
13
 
14
  ``` bnf
15
  h-pp-tokens:
16
+ h-preprocessing-token h-pp-tokensₒₚₜ
 
17
  ```
18
 
19
  ``` bnf
20
  header-name-tokens:
21
  string-literal
 
26
  has-include-expression:
27
  '__has_include' '(' header-name ')'
28
  '__has_include' '(' header-name-tokens ')'
29
  ```
30
 
31
+ ``` bnf
32
+ has-embed-expression:
33
+ '__has_embed' '(' header-name pp-balanced-token-seqₒₚₜ ')'
34
+ '__has_embed' '(' header-name-tokens pp-balanced-token-seqₒₚₜ ')'
35
+ ```
36
+
37
  ``` bnf
38
  has-attribute-expression:
39
  '__has_cpp_attribute (' pp-tokens ')'
40
  ```
41
 
42
  The expression that controls conditional inclusion shall be an integral
43
  constant expression except that identifiers (including those lexically
44
  identical to keywords) are interpreted as described below[^2]
45
 
46
+ and it may contain zero or more *defined-macro-expression*s,
47
+ *has-include-expression*s, *has-attribute-expression*s, and/or
48
+ *has-embed-expression*s as unary operator expressions. A
49
+ *defined-macro-expression* shall not appear within a
50
+ *has-include-expression* or *has-embed-expression*.
51
 
52
  A *defined-macro-expression* evaluates to `1` if the identifier is
53
  currently defined as a macro name (that is, if it is predefined or if it
54
  has one or more active macro definitions [[cpp.import]], for example
55
  because it has been the subject of a `#define` preprocessing directive
56
  without an intervening `#undef` directive with the same subject
57
  identifier), `0` if it is not.
58
 
 
 
 
 
59
  The header or source file identified by the parenthesized preprocessing
60
  token sequence in each contained *has-include-expression* is searched
61
+ for as if that preprocessing token sequence were the *pp-tokens* of a
62
  `#include` directive, except that no further macro expansion is
63
+ performed. If the preprocessing token sequence does not consist solely
64
+ of a *header-name* or cannot be combined [[cpp.include]] into a single
65
+ *header-name* preprocessing token, the program is ill-formed. The
66
  *has-include-expression* evaluates to `1` if the search for the source
67
  file succeeds, and to `0` if the search fails.
68
 
69
+ The parenthesized preprocessing token sequence of each contained
70
+ *has-embed-expression* is processed as if that preprocessing token
71
+ sequence were the *pp-tokens* of a `#embed` directive [[cpp.embed]],
72
+ except that no further macro expansion is performed. The
73
+ *has-embed-expression* evaluates to:
74
+
75
+ - `__STDC_EMBED_FOUND__` if the search for the resource succeeds, all
76
+ the given *embed-parameter*s in the *embed-parameter-seq* are
77
+ supported, and the resource is not empty.
78
+ - Otherwise, `__STDC_EMBED_EMPTY__` if the search for the resource
79
+ succeeds, all the given *embed-parameter*s in the
80
+ *embed-parameter-seq* are supported, and the resource is empty.
81
+ - Otherwise, `__STDC_EMBED_NOT_FOUND__`.
82
+
83
+ [*Note 1*: An unrecognized *embed-parameter* in an
84
+ *has-embed-expression* is not ill-formed and is instead treated as not
85
+ supported. — *end note*]
86
+
87
  Each *has-attribute-expression* is replaced by a non-zero *pp-number*
88
  matching the form of an *integer-literal* if the implementation supports
89
  an attribute with the name specified by interpreting the *pp-tokens*,
90
  after macro expansion, as an *attribute-token*, and by `0` otherwise.
91
  The program is ill-formed if the *pp-tokens* do not match the form of an
92
  *attribute-token*.
93
 
94
+ For an attribute specified in this document, it is
95
+ *implementation-defined* whether the value of the
96
+ *has-attribute-expression* is `0` or is given by [[cpp.cond.ha]]. For
97
+ other attributes recognized by the implementation, the value is
98
  *implementation-defined*.
99
 
100
+ [*Note 2*: It is expected that the availability of an attribute can be
101
  detected by any non-zero result. — *end note*]
102
 
103
  **Table: __has_cpp_attribute values** <a id="cpp.cond.ha">[cpp.cond.ha]</a>
104
 
105
  | Attribute | Value |
106
+ | ------------------- | --------- |
107
  | `assume` | `202207L` |
 
108
  | `deprecated` | `201309L` |
109
  | `fallthrough` | `201603L` |
110
+ | `indeterminate` | `202403L` |
111
  | `likely` | `201803L` |
112
  | `maybe_unused` | `201603L` |
113
  | `no_unique_address` | `201803L` |
114
  | `nodiscard` | `201907L` |
115
  | `noreturn` | `200809L` |
116
  | `unlikely` | `201803L` |
117
 
118
 
119
  The `#ifdef`, `#ifndef`, `#elifdef`, and `#elifndef` directives, and the
120
+ `defined` conditional inclusion operator, shall treat `__has_include`,
121
+ `__has_embed`, and `__has_cpp_attribute` as if they were the names of
122
+ defined macros. The identifiers `__has_include`, `__has_embed`, and
123
+ `__has_cpp_attribute` shall not appear in any context not mentioned in
124
+ this subclause.
125
 
126
  Each preprocessing token that remains (in the list of preprocessing
127
  tokens that will become the controlling expression) after all macro
128
  replacements have occurred shall be in the lexical form of a token
129
  [[lex.token]].
 
138
  check whether the controlling constant expression evaluates to nonzero.
139
 
140
  Prior to evaluation, macro invocations in the list of preprocessing
141
  tokens that will become the controlling constant expression are replaced
142
  (except for those macro names modified by the `defined` unary operator),
143
+ just as in normal text. If replacement of macros in the preprocessing
144
+ tokens following the sequence `\xname{has_embed} (` and before a
145
+ matching `)` (possibly produced by macro expansion) encounters a
146
+ preprocessing token that is one of the *identifier*s `limit`, `prefix`,
147
+ `suffix`, or `if_empty` and that *identifier* is defined as a macro
148
+ [[cpp.replace.general]], the program is ill-formed. If the preprocessing
149
+ token `defined` is generated as a result of this replacement process or
150
+ use of the `defined` unary operator does not match one of the two
151
+ specified forms prior to macro replacement, the program is ill-formed,
152
+ no diagnostic required.
153
 
154
  After all replacements due to macro expansion and evaluations of
155
+ *defined-macro-expression*s, *has-include-expression*s,
156
+ *has-embed-expression*s, and *has-attribute-expression*s have been
157
+ performed, all remaining identifiers and keywords, except for `true` and
158
+ `false`, are replaced with the *pp-number* `0`, and then each
159
+ preprocessing token is converted into a token.
160
 
161
+ [*Note 3*: An alternative token [[lex.digraph]] is not an identifier,
162
  even when its spelling consists entirely of letters and underscores.
163
  Therefore it is not subject to this replacement. — *end note*]
164
 
165
  The resulting tokens comprise the controlling constant expression which
166
  is evaluated according to the rules of  [[expr.const]] using arithmetic
167
  that has at least the ranges specified in  [[support.limits]]. For the
168
  purposes of this token conversion and evaluation all signed and unsigned
169
  integer types act as if they have the same representation as,
170
  respectively, `intmax_t` or `uintmax_t` [[cstdint.syn]].
171
 
172
+ [*Note 4*: Thus on an implementation where
173
  `std::numeric_limits<int>::max()` is `0x7FFF` and
174
  `std::numeric_limits<unsigned int>::max()` is `0xFFFF`, the integer
175
  literal `0x8000` is signed and positive within a `#if` expression even
176
  though it is unsigned in translation phase 7
177
  [[lex.phases]]. — *end note*]
178
 
179
  This includes interpreting *character-literal*s according to the rules
180
  in [[lex.ccon]].
181
 
182
+ [*Note 5*: The associated character encodings of literals are the same
183
  in `#if` and `#elif` directives and in any expression. — *end note*]
184
 
185
  Each subexpression with type `bool` is subjected to integral promotion
186
  before processing continues.
187
 
 
199
  `#if` `!defined` *identifier*, `#elif` `defined` *identifier*, and
200
  `#elif` `!defined` *identifier*, respectively.
201
 
202
  Each directive’s condition is checked in order. If it evaluates to false
203
  (zero), the group that it controls is skipped: directives are processed
204
+ only through the directive name that determines the directive in order
205
+ to keep track of the level of nested conditionals; the rest of the
206
+ directives’ preprocessing tokens are ignored, as are the other
207
+ preprocessing tokens in the group. Only the first group whose control
208
+ condition evaluates to true (nonzero) is processed; any following groups
209
+ are skipped and their controlling directives are processed as if they
210
+ were in a group that is skipped. If none of the conditions evaluates to
211
+ true, and there is a `#else` directive, the group controlled by the
212
+ `#else` is processed; lacking a `#else` directive, all the groups until
213
+ the `#endif` are skipped.[^3]
214
 
215
  [*Example 1*:
216
 
217
  This demonstrates a way to include a library `optional` facility only if
218
  it is available: