From Jason Turner

[cpp.cond]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpgm_3l339/{from.md → to.md} +110 -37
tmp/tmpgm_3l339/{from.md → to.md} RENAMED
@@ -15,55 +15,102 @@ h-preprocessing-token:
15
  h-pp-tokens:
16
  h-preprocessing-token
17
  h-pp-tokens h-preprocessing-token
18
  ```
19
 
 
 
 
 
 
 
20
  ``` bnf
21
  has-include-expression:
22
- '__has_include ( <' h-char-sequence '> )'
23
- '__has_include ( "' q-char-sequence '" )'
24
- '__has_include (' string-literal ')'
25
- '__has_include ( <' h-pp-tokens '> )'
 
 
 
26
  ```
27
 
28
  The expression that controls conditional inclusion shall be an integral
29
  constant expression except that identifiers (including those lexically
30
  identical to keywords) are interpreted as described below[^2] and it may
31
  contain zero or more *defined-macro-expression*s and/or
32
- *has-include-expression*s as unary operator expressions.
 
33
 
34
  A *defined-macro-expression* evaluates to `1` if the identifier is
35
  currently defined as a macro name (that is, if it is predefined or if it
36
- has been the subject of a `#define` preprocessing directive without an
37
- intervening `#undef` directive with the same subject identifier), `0` if
38
- it is not.
 
39
 
40
- The third and fourth forms of *has-include-expression* are considered
41
- only if neither of the first or second forms matches, in which case the
42
- preprocessing tokens are processed just as in normal text.
43
 
44
  The header or source file identified by the parenthesized preprocessing
45
  token sequence in each contained *has-include-expression* is searched
46
  for as if that preprocessing token sequence were the *pp-tokens* in a
47
  `#include` directive, except that no further macro expansion is
48
  performed. If such a directive would not satisfy the syntactic
49
  requirements of a `#include` directive, the program is ill-formed. The
50
  *has-include-expression* evaluates to `1` if the search for the source
51
  file succeeds, and to `0` if the search fails.
52
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
53
  The `#ifdef` and `#ifndef` directives, and the `defined` conditional
54
- inclusion operator, shall treat `__has_include` as if it were the name
55
- of a defined macro. The identifier `__has_include` shall not appear in
56
- any context not mentioned in this section.
 
57
 
58
  Each preprocessing token that remains (in the list of preprocessing
59
  tokens that will become the controlling expression) after all macro
60
- replacements have occurred shall be in the lexical form of a token (
61
- [[lex.token]]).
62
 
63
  Preprocessing directives of the forms
64
 
 
 
 
 
 
65
  check whether the controlling constant expression evaluates to nonzero.
66
 
67
  Prior to evaluation, macro invocations in the list of preprocessing
68
  tokens that will become the controlling constant expression are replaced
69
  (except for those macro names modified by the `defined` unary operator),
@@ -71,60 +118,65 @@ just as in normal text. If the token `defined` is generated as a result
71
  of this replacement process or use of the `defined` unary operator does
72
  not match one of the two specified forms prior to macro replacement, the
73
  behavior is undefined.
74
 
75
  After all replacements due to macro expansion and evaluations of
76
- *defined-macro-expression*s and *has-include-expression*s have been
77
- performed, all remaining identifiers and keywords, except for `true` and
78
- `false`, are replaced with the *pp-number* `0`, and then each
79
- preprocessing token is converted into a token.
 
80
 
81
- [*Note 1*: An alternative token ([[lex.digraph]]) is not an
82
- identifier, even when its spelling consists entirely of letters and
83
- underscores. Therefore it is not subject to this
84
- replacement. — *end note*]
85
 
86
  The resulting tokens comprise the controlling constant expression which
87
  is evaluated according to the rules of  [[expr.const]] using arithmetic
88
  that has at least the ranges specified in  [[support.limits]]. For the
89
  purposes of this token conversion and evaluation all signed and unsigned
90
  integer types act as if they have the same representation as,
91
- respectively, `intmax_t` or `uintmax_t` ([[cstdint]]).
92
 
93
- [*Note 2*: Thus on an implementation where
94
  `std::numeric_limits<int>::max()` is `0x7FFF` and
95
  `std::numeric_limits<unsigned int>::max()` is `0xFFFF`, the integer
96
  literal `0x8000` is signed and positive within a `#if` expression even
97
- though it is unsigned in translation phase 7 (
98
- [[lex.phases]]). — *end note*]
99
 
100
- This includes interpreting character literals, which may involve
101
  converting escape sequences into execution character set members.
102
- Whether the numeric value for these character literals matches the value
103
- obtained when an identical character literal occurs in an expression
104
- (other than within a `#if` or `#elif` directive) is
105
  *implementation-defined*.
106
 
107
- [*Note 3*:
108
 
109
  Thus, the constant expression in the following `#if` directive and `if`
110
- statement is not guaranteed to evaluate to the same value in these two
111
- contexts:
112
 
113
  ``` cpp
114
  #if 'z' - 'a' == 25
115
  if ('z' - 'a' == 25)
116
  ```
117
 
118
  — *end note*]
119
 
120
- Also, whether a single-character character literal may have a negative
121
  value is *implementation-defined*. Each subexpression with type `bool`
122
  is subjected to integral promotion before processing continues.
123
 
124
  Preprocessing directives of the forms
125
 
 
 
 
 
 
126
  check whether the identifier is or is not currently defined as a macro
127
  name. Their conditions are equivalent to `#if` `defined` *identifier*
128
  and `#if` `!defined` *identifier* respectively.
129
 
130
  Each directive’s condition is checked in order. If it evaluates to false
@@ -146,17 +198,38 @@ This demonstrates a way to include a library `optional` facility only if
146
  it is available:
147
 
148
  ``` cpp
149
  #if __has_include(<optional>)
150
  # include <optional>
 
151
  # define have_optional 1
 
152
  #elif __has_include(<experimental/optional>)
153
  # include <experimental/optional>
 
154
  # define have_optional 1
155
  # define experimental_optional 1
156
- #else
 
 
157
  # define have_optional 0
158
  #endif
159
  ```
160
 
161
  — *end example*]
162
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
23
+ '<' h-pp-tokens '>'
24
+ ```
25
+
26
  ``` bnf
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] and it may
40
  contain zero or more *defined-macro-expression*s and/or
41
+ *has-include-expression*s and/or *has-attribute-expression*s as unary
42
+ operator expressions.
43
 
44
  A *defined-macro-expression* evaluates to `1` if the identifier is
45
  currently defined as a macro name (that is, if it is predefined or if it
46
+ has one or more active macro definitions [[cpp.import]], for example
47
+ because it has been the subject of a `#define` preprocessing directive
48
+ without an intervening `#undef` directive with the same subject
49
+ identifier), `0` if it is not.
50
 
51
+ The second form of *has-include-expression* is considered only if the
52
+ first form does not match, in which case the preprocessing tokens are
53
+ processed just as in normal text.
54
 
55
  The header or source file identified by the parenthesized preprocessing
56
  token sequence in each contained *has-include-expression* is searched
57
  for as if that preprocessing token sequence were the *pp-tokens* in a
58
  `#include` directive, except that no further macro expansion is
59
  performed. If such a directive would not satisfy the syntactic
60
  requirements of a `#include` directive, the program is ill-formed. The
61
  *has-include-expression* evaluates to `1` if the search for the source
62
  file succeeds, and to `0` if the search fails.
63
 
64
+ Each *has-attribute-expression* is replaced by a non-zero *pp-number*
65
+ matching the form of an *integer-literal* if the implementation supports
66
+ an attribute with the name specified by interpreting the *pp-tokens*,
67
+ after macro expansion, as an *attribute-token*, and by `0` otherwise.
68
+ The program is ill-formed if the *pp-tokens* do not match the form of an
69
+ *attribute-token*.
70
+
71
+ For an attribute specified in this document, the value of the
72
+ *has-attribute-expression* is given by [[cpp.cond.ha]]. For other
73
+ attributes recognized by the implementation, the value is
74
+ *implementation-defined*.
75
+
76
+ [*Note 1*: It is expected that the availability of an attribute can be
77
+ detected by any non-zero result. — *end note*]
78
+
79
+ **Table: __has_cpp_attribute values** <a id="cpp.cond.ha">[cpp.cond.ha]</a>
80
+
81
+ | Attribute | Value |
82
+ | -------------------- | --------- |
83
+ | `carries_dependency` | `200809L` |
84
+ | `deprecated` | `201309L` |
85
+ | `fallthrough` | `201603L` |
86
+ | `likely` | `201803L` |
87
+ | `maybe_unused` | `201603L` |
88
+ | `no_unique_address` | `201803L` |
89
+ | `nodiscard` | `201907L` |
90
+ | `noreturn` | `200809L` |
91
+ | `unlikely` | `201803L` |
92
+
93
+
94
  The `#ifdef` and `#ifndef` directives, and the `defined` conditional
95
+ inclusion operator, shall treat `__has_include` and
96
+ `__has_cpp_attribute` as if they were the names of defined macros. The
97
+ identifiers `__has_include` and `__has_cpp_attribute` shall not appear
98
+ in any context not mentioned in this subclause.
99
 
100
  Each preprocessing token that remains (in the list of preprocessing
101
  tokens that will become the controlling expression) after all macro
102
+ replacements have occurred shall be in the lexical form of a token
103
+ [[lex.token]].
104
 
105
  Preprocessing directives of the forms
106
 
107
+ ``` bnf
108
+ '# if ' constant-expression new-line groupₒₚₜ
109
+ '# elif ' constant-expression new-line groupₒₚₜ
110
+ ```
111
+
112
  check whether the controlling constant expression evaluates to nonzero.
113
 
114
  Prior to evaluation, macro invocations in the list of preprocessing
115
  tokens that will become the controlling constant expression are replaced
116
  (except for those macro names modified by the `defined` unary operator),
 
118
  of this replacement process or use of the `defined` unary operator does
119
  not match one of the two specified forms prior to macro replacement, the
120
  behavior is undefined.
121
 
122
  After all replacements due to macro expansion and evaluations of
123
+ *defined-macro-expression*s, *has-include-expression*s, and
124
+ *has-attribute-expression*s have been performed, all remaining
125
+ identifiers and keywords, except for `true` and `false`, are replaced
126
+ with the *pp-number* `0`, and then each preprocessing token is converted
127
+ into a token.
128
 
129
+ [*Note 2*: An alternative token [[lex.digraph]] is not an identifier,
130
+ even when its spelling consists entirely of letters and underscores.
131
+ Therefore it is not subject to this replacement. — *end note*]
 
132
 
133
  The resulting tokens comprise the controlling constant expression which
134
  is evaluated according to the rules of  [[expr.const]] using arithmetic
135
  that has at least the ranges specified in  [[support.limits]]. For the
136
  purposes of this token conversion and evaluation all signed and unsigned
137
  integer types act as if they have the same representation as,
138
+ respectively, `intmax_t` or `uintmax_t` [[cstdint]].
139
 
140
+ [*Note 3*: Thus on an implementation where
141
  `std::numeric_limits<int>::max()` is `0x7FFF` and
142
  `std::numeric_limits<unsigned int>::max()` is `0xFFFF`, the integer
143
  literal `0x8000` is signed and positive within a `#if` expression even
144
+ though it is unsigned in translation phase 7
145
+ [[lex.phases]]. — *end note*]
146
 
147
+ This includes interpreting *character-literal*s, which may involve
148
  converting escape sequences into execution character set members.
149
+ Whether the numeric value for these *character-literal*s matches the
150
+ value obtained when an identical *character-literal* occurs in an
151
+ expression (other than within a `#if` or `#elif` directive) is
152
  *implementation-defined*.
153
 
154
+ [*Note 4*:
155
 
156
  Thus, the constant expression in the following `#if` directive and `if`
157
+ statement [[stmt.if]] is not guaranteed to evaluate to the same value in
158
+ these two contexts:
159
 
160
  ``` cpp
161
  #if 'z' - 'a' == 25
162
  if ('z' - 'a' == 25)
163
  ```
164
 
165
  — *end note*]
166
 
167
+ Also, whether a single-character *character-literal* may have a negative
168
  value is *implementation-defined*. Each subexpression with type `bool`
169
  is subjected to integral promotion before processing continues.
170
 
171
  Preprocessing directives of the forms
172
 
173
+ ``` bnf
174
+ '# ifdef ' identifier new-line groupₒₚₜ
175
+ '# ifndef ' identifier new-line groupₒₚₜ
176
+ ```
177
+
178
  check whether the identifier is or is not currently defined as a macro
179
  name. Their conditions are equivalent to `#if` `defined` *identifier*
180
  and `#if` `!defined` *identifier* respectively.
181
 
182
  Each directive’s condition is checked in order. If it evaluates to false
 
198
  it is available:
199
 
200
  ``` cpp
201
  #if __has_include(<optional>)
202
  # include <optional>
203
+ # if __cpp_lib_optional >= 201603
204
  # define have_optional 1
205
+ # endif
206
  #elif __has_include(<experimental/optional>)
207
  # include <experimental/optional>
208
+ # if __cpp_lib_experimental_optional >= 201411
209
  # define have_optional 1
210
  # define experimental_optional 1
211
+ # endif
212
+ #endif
213
+ #ifndef have_optional
214
  # define have_optional 0
215
  #endif
216
  ```
217
 
218
  — *end example*]
219
 
220
+ [*Example 2*:
221
+
222
+ This demonstrates a way to use the attribute `[[acme::deprecated]]` only
223
+ if it is available.
224
+
225
+ ``` cpp
226
+ #if __has_cpp_attribute(acme::deprecated)
227
+ # define ATTR_DEPRECATED(msg) [[acme::deprecated(msg)]]
228
+ #else
229
+ # define ATTR_DEPRECATED(msg) [[deprecated(msg)]]
230
+ #endif
231
+ ATTR_DEPRECATED("This function is deprecated") void anvil();
232
+ ```
233
+
234
+ — *end example*]
235
+