From Jason Turner

[dcl.pre]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpgcy0rlki/{from.md → to.md} +129 -26
tmp/tmpgcy0rlki/{from.md → to.md} RENAMED
@@ -3,12 +3,11 @@
3
  Declarations generally specify how names are to be interpreted.
4
  Declarations have the form
5
 
6
  ``` bnf
7
  declaration-seq:
8
- declaration
9
- declaration-seq declaration
10
  ```
11
 
12
  ``` bnf
13
  declaration:
14
  name-declaration
@@ -18,10 +17,11 @@ declaration:
18
  ``` bnf
19
  name-declaration:
20
  block-declaration
21
  nodeclspec-function-declaration
22
  function-definition
 
23
  template-declaration
24
  deduction-guide
25
  linkage-specification
26
  namespace-definition
27
  empty-declaration
@@ -43,10 +43,11 @@ block-declaration:
43
  namespace-alias-definition
44
  using-declaration
45
  using-enum-declaration
46
  using-directive
47
  static_assert-declaration
 
48
  alias-declaration
49
  opaque-enum-declaration
50
  ```
51
 
52
  ``` bnf
@@ -57,21 +58,48 @@ nodeclspec-function-declaration:
57
  ``` bnf
58
  alias-declaration:
59
  using identifier attribute-specifier-seqₒₚₜ '=' defining-type-id ';'
60
  ```
61
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
62
  ``` bnf
63
  simple-declaration:
64
  decl-specifier-seq init-declarator-listₒₚₜ ';'
65
  attribute-specifier-seq decl-specifier-seq init-declarator-list ';'
66
- attribute-specifier-seqₒₚₜ decl-specifier-seq ref-qualifierₒₚₜ '[' identifier-list ']' initializer ';'
 
 
 
 
 
 
67
  ```
68
 
69
  ``` bnf
70
  static_assert-declaration:
71
  static_assert '(' constant-expression ')' ';'
72
- static_assert '(' constant-expression ',' string-literal ')' ';'
 
 
 
 
 
73
  ```
74
 
75
  ``` bnf
76
  empty-declaration:
77
  ';'
@@ -90,15 +118,18 @@ attribute-declaration:
90
  [[namespace.def]], *using-declaration*s are described in 
91
  [[namespace.udecl]] and *using-directive*s are described in 
92
  [[namespace.udir]]. — *end note*]
93
 
94
  Certain declarations contain one or more scopes [[basic.scope.scope]].
95
- Unless otherwise stated, utterances in [[dcl.dcl]] about components in,
96
- of, or contained by a declaration or subcomponent thereof refer only to
97
  those components of the declaration that are *not* nested within scopes
98
  nested within the declaration.
99
 
 
 
 
100
  A *simple-declaration* or *nodeclspec-function-declaration* of the form
101
 
102
  ``` bnf
103
  attribute-specifier-seqₒₚₜ decl-specifier-seqₒₚₜ init-declarator-listₒₚₜ ';'
104
  ```
@@ -151,14 +182,18 @@ enum { }; // error
151
  typedef class { }; // error
152
  ```
153
 
154
  — *end example*]
155
 
156
- A *simple-declaration* with an *identifier-list* is called a *structured
157
- binding declaration* [[dcl.struct.bind]]. Each *decl-specifier* in the
158
- *decl-specifier-seq* shall be `static`, `thread_local`, `auto`
159
- [[dcl.spec.auto]], or a *cv-qualifier*.
 
 
 
 
160
 
161
  [*Example 3*:
162
 
163
  ``` cpp
164
  template<class T> concept C = true;
@@ -168,17 +203,18 @@ C auto [x, y] = std::pair{1, 2}; // error: constrained placeholder-type-speci
168
 
169
  — *end example*]
170
 
171
  The *initializer* shall be of the form “`=` *assignment-expression*”, of
172
  the form “`{` *assignment-expression* `}`”, or of the form “`(`
173
- *assignment-expression* `)`”, where the *assignment-expression* is of
 
 
174
  array or non-union class type.
175
 
176
  If the *decl-specifier-seq* contains the `typedef` specifier, the
177
  declaration is a *typedef declaration* and each *declarator-id* is
178
- declared to be a *typedef-name*, synonymous with its associated type
179
- [[dcl.typedef]].
180
 
181
  [*Note 4*: Such a *declarator-id* is an *identifier*
182
  [[class.conv.fct]]. — *end note*]
183
 
184
  Otherwise, if the type associated with a *declarator-id* is a function
@@ -195,36 +231,71 @@ extern void g(), // OK, function declaration for g
195
  y; // error: void is not an object type
196
  ```
197
 
198
  — *end example*]
199
 
 
 
 
200
  Syntactic components beyond those found in the general form of
201
  *simple-declaration* are added to a function declaration to make a
202
- *function-definition*. An object declaration, however, is also a
203
- definition unless it contains the `extern` specifier and has no
204
- initializer [[basic.def]]. An object definition causes storage of
205
- appropriate size and alignment to be reserved and any appropriate
206
- initialization [[dcl.init]] to be done.
 
 
 
 
 
207
 
208
  A *nodeclspec-function-declaration* shall declare a constructor,
209
  destructor, or conversion function.
210
 
211
- [*Note 5*: Because a member function cannot be subject to a
212
  non-defining declaration outside of a class definition [[class.mfct]], a
213
  *nodeclspec-function-declaration* can only be used in a
214
  *template-declaration* [[temp.pre]], *explicit-instantiation*
215
  [[temp.explicit]], or *explicit-specialization*
216
  [[temp.expl.spec]]. — *end note*]
217
 
218
- In a *static_assert-declaration*, the *constant-expression* is
 
 
 
 
 
 
 
 
 
 
219
  contextually converted to `bool` and the converted expression shall be a
220
- constant expression [[expr.const]]. If the value of the expression when
221
- so converted is `true` or the expression is evaluated in the context of
222
- a template definition, the declaration has no effect. Otherwise, the
223
- *static_assert-declaration* *fails*, the program is ill-formed, and the
224
- resulting diagnostic message [[intro.compliance]] should include the
225
- text of the *string-literal*, if one is supplied.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
226
 
227
  [*Example 5*:
228
 
229
  ``` cpp
230
  static_assert(sizeof(int) == sizeof(void*), "wrong pointer size");
@@ -245,10 +316,42 @@ void g(char c) {
245
  }
246
  ```
247
 
248
  — *end example*]
249
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
250
  An *empty-declaration* has no effect.
251
 
252
  Except where otherwise specified, the meaning of an
253
  *attribute-declaration* is *implementation-defined*.
254
 
 
3
  Declarations generally specify how names are to be interpreted.
4
  Declarations have the form
5
 
6
  ``` bnf
7
  declaration-seq:
8
+ declaration declaration-seqₒₚₜ
 
9
  ```
10
 
11
  ``` bnf
12
  declaration:
13
  name-declaration
 
17
  ``` bnf
18
  name-declaration:
19
  block-declaration
20
  nodeclspec-function-declaration
21
  function-definition
22
+ friend-type-declaration
23
  template-declaration
24
  deduction-guide
25
  linkage-specification
26
  namespace-definition
27
  empty-declaration
 
43
  namespace-alias-definition
44
  using-declaration
45
  using-enum-declaration
46
  using-directive
47
  static_assert-declaration
48
+ consteval-block-declaration
49
  alias-declaration
50
  opaque-enum-declaration
51
  ```
52
 
53
  ``` bnf
 
58
  ``` bnf
59
  alias-declaration:
60
  using identifier attribute-specifier-seqₒₚₜ '=' defining-type-id ';'
61
  ```
62
 
63
+ ``` bnf
64
+ sb-identifier:
65
+ '...'ₒₚₜ identifier attribute-specifier-seqₒₚₜ
66
+ ```
67
+
68
+ ``` bnf
69
+ sb-identifier-list:
70
+ sb-identifier
71
+ sb-identifier-list ',' sb-identifier
72
+ ```
73
+
74
+ ``` bnf
75
+ structured-binding-declaration:
76
+ attribute-specifier-seqₒₚₜ decl-specifier-seq ref-qualifierₒₚₜ '[' sb-identifier-list ']'
77
+ ```
78
+
79
  ``` bnf
80
  simple-declaration:
81
  decl-specifier-seq init-declarator-listₒₚₜ ';'
82
  attribute-specifier-seq decl-specifier-seq init-declarator-list ';'
83
+ structured-binding-declaration initializer ';'
84
+ ```
85
+
86
+ ``` bnf
87
+ static_assert-message:
88
+ unevaluated-string
89
+ constant-expression
90
  ```
91
 
92
  ``` bnf
93
  static_assert-declaration:
94
  static_assert '(' constant-expression ')' ';'
95
+ static_assert '(' constant-expression ',' static_assert-message ')' ';'
96
+ ```
97
+
98
+ ``` bnf
99
+ consteval-block-declaration:
100
+ consteval compound-statement
101
  ```
102
 
103
  ``` bnf
104
  empty-declaration:
105
  ';'
 
118
  [[namespace.def]], *using-declaration*s are described in 
119
  [[namespace.udecl]] and *using-directive*s are described in 
120
  [[namespace.udir]]. — *end note*]
121
 
122
  Certain declarations contain one or more scopes [[basic.scope.scope]].
123
+ Unless otherwise stated, utterances in [[dcl]] about components in, of,
124
+ or contained by a declaration or subcomponent thereof refer only to
125
  those components of the declaration that are *not* nested within scopes
126
  nested within the declaration.
127
 
128
+ If a *name-declaration* matches the syntactic requirements of
129
+ *friend-type-declaration*, it is a *friend-type-declaration*.
130
+
131
  A *simple-declaration* or *nodeclspec-function-declaration* of the form
132
 
133
  ``` bnf
134
  attribute-specifier-seqₒₚₜ decl-specifier-seqₒₚₜ init-declarator-listₒₚₜ ';'
135
  ```
 
182
  typedef class { }; // error
183
  ```
184
 
185
  — *end example*]
186
 
187
+ A *simple-declaration* or a *condition* with a
188
+ *structured-binding-declaration* is called a *structured binding
189
+ declaration* [[dcl.struct.bind]]. Each *decl-specifier* in the
190
+ *decl-specifier-seq* shall be `constexpr`, `constinit`, `static`,
191
+ `thread_local`, `auto` [[dcl.spec.auto]], or a *cv-qualifier*. The
192
+ declaration shall contain at most one *sb-identifier* whose *identifier*
193
+ is preceded by an ellipsis. If the declaration contains any such
194
+ *sb-identifier*, it shall declare a templated entity [[temp.pre]].
195
 
196
  [*Example 3*:
197
 
198
  ``` cpp
199
  template<class T> concept C = true;
 
203
 
204
  — *end example*]
205
 
206
  The *initializer* shall be of the form “`=` *assignment-expression*”, of
207
  the form “`{` *assignment-expression* `}`”, or of the form “`(`
208
+ *assignment-expression* `)`”. If the *structured-binding-declaration*
209
+ appears as a *condition*, the *assignment-expression* shall be of
210
+ non-union class type. Otherwise, the *assignment-expression* shall be of
211
  array or non-union class type.
212
 
213
  If the *decl-specifier-seq* contains the `typedef` specifier, the
214
  declaration is a *typedef declaration* and each *declarator-id* is
215
+ declared to be a *typedef-name* [[dcl.typedef]].
 
216
 
217
  [*Note 4*: Such a *declarator-id* is an *identifier*
218
  [[class.conv.fct]]. — *end note*]
219
 
220
  Otherwise, if the type associated with a *declarator-id* is a function
 
231
  y; // error: void is not an object type
232
  ```
233
 
234
  — *end example*]
235
 
236
+ An object definition causes storage of appropriate size and alignment to
237
+ be reserved and any appropriate initialization [[dcl.init]] to be done.
238
+
239
  Syntactic components beyond those found in the general form of
240
  *simple-declaration* are added to a function declaration to make a
241
+ *function-definition*. A token sequence starting with `{` or `=` is
242
+ treated as a *function-body* [[dcl.fct.def.general]] if the type of the
243
+ *declarator-id* [[dcl.meaning.general]] is a function type, and is
244
+ otherwise treated as a *brace-or-equal-initializer*
245
+ [[dcl.init.general]].
246
+
247
+ [*Note 5*: If the declaration acquires a function type through template
248
+ instantiation, the program is ill-formed; see [[temp.spec.general]]. The
249
+ function type of a function definition cannot be specified with a
250
+ *typedef-name* [[dcl.fct]]. — *end note*]
251
 
252
  A *nodeclspec-function-declaration* shall declare a constructor,
253
  destructor, or conversion function.
254
 
255
+ [*Note 6*: Because a member function cannot be subject to a
256
  non-defining declaration outside of a class definition [[class.mfct]], a
257
  *nodeclspec-function-declaration* can only be used in a
258
  *template-declaration* [[temp.pre]], *explicit-instantiation*
259
  [[temp.explicit]], or *explicit-specialization*
260
  [[temp.expl.spec]]. — *end note*]
261
 
262
+ If a *static_assert-message* matches the syntactic requirements of
263
+ *unevaluated-string*, it is an *unevaluated-string* and the text of the
264
+ *static_assert-message* is the text of the *unevaluated-string*.
265
+ Otherwise, a *static_assert-message* shall be an expression M such that
266
+
267
+ - the expression `M.size()` is implicitly convertible to the type
268
+ `std::size_t`, and
269
+ - the expression `M.data()` is implicitly convertible to the type
270
+ “pointer to `const char`”.
271
+
272
+ In a *static_assert-declaration*, the *constant-expression* E is
273
  contextually converted to `bool` and the converted expression shall be a
274
+ constant expression [[expr.const]]. If the value of the expression E
275
+ when so converted is `true` or the expression is evaluated in the
276
+ context of a template definition, the declaration has no effect and the
277
+ *static_assert-message* is an unevaluated operand
278
+ [[term.unevaluated.operand]]. Otherwise, the *static_assert-declaration*
279
+ *fails* and
280
+
281
+ - the program is ill-formed, and
282
+ - if the *static_assert-message* is a *constant-expression* M,
283
+ - `M.size()` shall be a converted constant expression of type
284
+ `std::size_t` and let N denote the value of that expression,
285
+ - `M.data()`, implicitly converted to the type “pointer to
286
+ `const char`”, shall be a core constant expression and let D denote
287
+ the converted expression,
288
+ - for each i where 0 ≤ i < N, `D[i]` shall be an integral constant
289
+ expression, and
290
+ - the text of the *static_assert-message* is formed by the sequence of
291
+ N code units, starting at D, of the ordinary literal encoding
292
+ [[lex.charset]].
293
+
294
+ *Recommended practice:* When a *static_assert-declaration* fails, the
295
+ resulting diagnostic message should include the text of the
296
+ *static_assert-message*, if one is supplied.
297
 
298
  [*Example 5*:
299
 
300
  ``` cpp
301
  static_assert(sizeof(int) == sizeof(void*), "wrong pointer size");
 
316
  }
317
  ```
318
 
319
  — *end example*]
320
 
321
+ For a *consteval-block-declaration* D, the expression E corresponding to
322
+ D is:
323
+
324
+ ``` cpp
325
+ []static consteval -> void compound-statement ()
326
+ ```
327
+
328
+ E shall be a constant expression [[expr.const]].
329
+
330
+ [*Note 7*: The evaluation of the expression corresponding to a
331
+ *consteval-block-declaration* [[lex.phases]] can produce injected
332
+ declarations as side effects. — *end note*]
333
+
334
+ [*Example 6*:
335
+
336
+ ``` cpp
337
+ struct S;
338
+ consteval {
339
+ std::meta::define_aggregate(^^S, {}); // OK
340
+
341
+ template<class T>
342
+ struct X { }; // error: local templates are not allowed
343
+
344
+ template<class T>
345
+ concept C = true; // error: local concepts are not allowed
346
+
347
+ return; // OK
348
+ }
349
+ ```
350
+
351
+ — *end example*]
352
+
353
  An *empty-declaration* has no effect.
354
 
355
  Except where otherwise specified, the meaning of an
356
  *attribute-declaration* is *implementation-defined*.
357