From Jason Turner

[dcl.attr]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpl3l2g_u5/{from.md → to.md} +279 -107
tmp/tmpl3l2g_u5/{from.md → to.md} RENAMED
@@ -10,20 +10,25 @@ attribute-specifier-seq:
10
  attribute-specifier-seqₒₚₜ attribute-specifier
11
  ```
12
 
13
  ``` bnf
14
  attribute-specifier:
15
- '[' '[' attribute-list ']' ']'
16
  alignment-specifier
17
  ```
18
 
19
  ``` bnf
20
  alignment-specifier:
21
  'alignas (' type-id '...'ₒₚₜ ')'
22
  'alignas (' constant-expression '...'ₒₚₜ ')'
23
  ```
24
 
 
 
 
 
 
25
  ``` bnf
26
  attribute-list:
27
  attributeₒₚₜ
28
  attribute-list ',' attributeₒₚₜ
29
  attribute '...'
@@ -51,84 +56,114 @@ attribute-namespace:
51
  identifier
52
  ```
53
 
54
  ``` bnf
55
  attribute-argument-clause:
56
- '(' balanced-token-seq ')'
57
  ```
58
 
59
  ``` bnf
60
  balanced-token-seq:
61
- balanced-tokenₒₚₜ
62
  balanced-token-seq balanced-token
63
  ```
64
 
65
  ``` bnf
66
  balanced-token:
67
- '(' balanced-token-seq ')'
68
- '[' balanced-token-seq ']'
69
- '{' balanced-token-seq '}'
70
  any *token* other than a parenthesis, a bracket, or a brace
71
  ```
72
 
73
- For each individual attribute, the form of the *balanced-token-seq* will
74
- be specified.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
75
 
76
  In an *attribute-list*, an ellipsis may appear only if that
77
  *attribute*’s specification permits it. An *attribute* followed by an
78
  ellipsis is a pack expansion ([[temp.variadic]]). An
79
  *attribute-specifier* that contains no *attribute*s has no effect. The
80
- order in which the *attribute-tokens* appear in an *attribute-list* is
81
  not significant. If a keyword ([[lex.key]]) or an alternative token (
82
  [[lex.digraph]]) that satisfies the syntactic requirements of an
83
  *identifier* ([[lex.name]]) is contained in an *attribute-token*, it is
84
  considered an identifier. No name lookup ([[basic.lookup]]) is
85
  performed on any of the identifiers contained in an *attribute-token*.
86
  The *attribute-token* determines additional requirements on the
87
- *attribute-argument-clause* (if any). The use of an
88
- *attribute-scoped-token* is conditionally-supported, with
89
- *implementation-defined* behavior. Each implementation should choose a
90
- distinctive name for the *attribute-namespace* in an
91
- *attribute-scoped-token*.
92
 
93
  Each *attribute-specifier-seq* is said to *appertain* to some entity or
94
  statement, identified by the syntactic context where it appears (Clause 
95
  [[stmt.stmt]], Clause  [[dcl.dcl]], Clause  [[dcl.decl]]). If an
96
  *attribute-specifier-seq* that appertains to some entity or statement
97
- contains an *attribute* that is not allowed to apply to that entity or
98
- statement, the program is ill-formed. If an *attribute-specifier-seq*
99
- appertains to a friend declaration ([[class.friend]]), that declaration
100
- shall be a definition. No *attribute-specifier-seq* shall appertain to
101
- an explicit instantiation ([[temp.explicit]]).
 
102
 
103
- For an *attribute-token* not specified in this International Standard,
104
- the behavior is *implementation-defined*.
 
 
 
 
 
105
 
106
  Two consecutive left square bracket tokens shall appear only when
107
- introducing an *attribute-specifier*. If two consecutive left square
108
- brackets appear where an *attribute-specifier* is not allowed, the
109
- program is ill-formed even if the brackets match an alternative grammar
110
- production.
 
 
 
 
111
 
112
  ``` cpp
113
  int p[10];
114
  void f() {
115
  int x = 42, y[5];
116
- int(p[[x] { return x; }()]); // error: invalid attribute on a nested
117
- // declarator-id and not a function-style cast of
118
- // an element of p.
119
- y[[] { return 2; }()] = 2; // error even though attributes are not allowed
120
- // in this context.
121
  }
122
  ```
123
 
 
 
124
  ### Alignment specifier <a id="dcl.align">[[dcl.align]]</a>
125
 
126
  An *alignment-specifier* may be applied to a variable or to a class data
127
  member, but it shall not be applied to a bit-field, a function
128
- parameter, an *exception-declaration* ([[except.handle]]), or a
129
- variable declared with the `register` storage class specifier. An
130
  *alignment-specifier* may also be applied to the declaration or
131
  definition of a class (in an *elaborated-type-specifier* (
132
  [[dcl.type.elab]]) or *class-head* (Clause  [[class]]), respectively)
133
  and to the declaration or definition of an enumeration (in an
134
  *opaque-enum-declaration* or *enum-head*, respectively ([[dcl.enum]])).
@@ -137,103 +172,85 @@ An *alignment-specifier* with an ellipsis is a pack expansion (
137
 
138
  When the *alignment-specifier* is of the form `alignas(`
139
  *constant-expression* `)`:
140
 
141
  - the *constant-expression* shall be an integral constant expression
142
- - if the constant expression evaluates to a fundamental alignment, the
143
- alignment requirement of the declared entity shall be the specified
144
- fundamental alignment
145
- - if the constant expression evaluates to an extended alignment and the
146
- implementation supports that alignment in the context of the
147
- declaration, the alignment of the declared entity shall be that
148
- alignment
149
- - if the constant expression evaluates to an extended alignment and the
150
  implementation does not support that alignment in the context of the
151
- declaration, the program is ill-formed
152
- - if the constant expression evaluates to zero, the alignment specifier
153
- shall have no effect
154
- - otherwise, the program is ill-formed.
155
 
156
- When the *alignment-specifier* is of the form `alignas(` *type-id* `)`,
157
- it shall have the same effect as `alignas({}alignof(`*type-id*`))` (
158
- [[expr.alignof]]).
159
 
160
- When multiple *alignment-specifier*s are specified for an entity, the
161
- alignment requirement shall be set to the strictest specified alignment.
 
162
 
163
  The combined effect of all *alignment-specifier*s in a declaration shall
164
  not specify an alignment that is less strict than the alignment that
165
  would be required for the entity being declared if all
166
- *alignment-specifier*s were omitted (including those in other
167
- declarations).
 
 
 
 
 
 
 
 
 
 
168
 
169
  If the defining declaration of an entity has an *alignment-specifier*,
170
  any non-defining declaration of that entity shall either specify
171
  equivalent alignment or have no *alignment-specifier*. Conversely, if
172
  any declaration of an entity has an *alignment-specifier*, every
173
  defining declaration of that entity shall specify an equivalent
174
  alignment. No diagnostic is required if declarations of an entity have
175
  different *alignment-specifier*s in different translation units.
176
 
 
 
177
  ``` cpp
178
  // Translation unit #1:
179
- struct S { int x; } s, p = &s;
180
 
181
  // Translation unit #2:
182
- struct alignas(16) S; // error: definition of S lacks alignment; no
183
- extern S* p; // diagnostic required
184
  ```
185
 
 
 
 
 
186
  An aligned buffer with an alignment requirement of `A` and holding `N`
187
- elements of type `T` other than `char`, `signed char`, or
188
- `unsigned char` can be declared as:
189
 
190
  ``` cpp
191
  alignas(T) alignas(A) T buffer[N];
192
  ```
193
 
194
  Specifying `alignas(T)` ensures that the final requested alignment will
195
  not be weaker than `alignof(T)`, and therefore the program will not be
196
  ill-formed.
197
 
 
 
 
 
198
  ``` cpp
199
  alignas(double) void f(); // error: alignment applied to function
200
  alignas(double) unsigned char c[sizeof(double)]; // array of characters, suitably aligned for a double
201
  extern unsigned char c[sizeof(double)]; // no alignas necessary
202
  alignas(float)
203
  extern unsigned char c[sizeof(double)]; // error: different alignment in declaration
204
  ```
205
 
206
- ### Noreturn attribute <a id="dcl.attr.noreturn">[[dcl.attr.noreturn]]</a>
207
-
208
- The *attribute-token* `noreturn` specifies that a function does not
209
- return. It shall appear at most once in each *attribute-list* and no
210
- *attribute-argument-clause* shall be present. The attribute may be
211
- applied to the *declarator-id* in a function declaration. The first
212
- declaration of a function shall specify the `noreturn` attribute if any
213
- declaration of that function specifies the `noreturn` attribute. If a
214
- function is declared with the `noreturn` attribute in one translation
215
- unit and the same function is declared without the `noreturn` attribute
216
- in another translation unit, the program is ill-formed; no diagnostic
217
- required.
218
-
219
- If a function `f` is called where `f` was previously declared with the
220
- `noreturn` attribute and `f` eventually returns, the behavior is
221
- undefined. The function may terminate by throwing an exception.
222
- Implementations are encouraged to issue a warning if a function marked
223
- `[[noreturn]]` might return.
224
-
225
- ``` cpp
226
- [[ noreturn ]] void f() {
227
- throw "error"; // OK
228
- }
229
-
230
- [[ noreturn ]] void q(int i) { // behavior is undefined if called with an argument <= 0
231
- if (i > 0)
232
- throw "positive";
233
- }
234
- ```
235
 
236
  ### Carries dependency attribute <a id="dcl.attr.depend">[[dcl.attr.depend]]</a>
237
 
238
  The *attribute-token* `carries_dependency` specifies dependency
239
  propagation into and out of functions. It shall appear at most once in
@@ -256,14 +273,17 @@ declaration of that function specifies the `carries_dependency`
256
  attribute for that parameter. If a function or one of its parameters is
257
  declared with the `carries_dependency` attribute in its first
258
  declaration in one translation unit and the same function or one of its
259
  parameters is declared without the `carries_dependency` attribute in its
260
  first declaration in another translation unit, the program is
261
- ill-formed; no diagnostic required.
262
 
263
- The `carries_dependency` attribute does not change the meaning of the
264
- program, but may result in generation of more efficient code.
 
 
 
265
 
266
  ``` cpp
267
  /* Translation unit A. */
268
 
269
  struct foo { int* a; int* b; };
@@ -304,42 +324,194 @@ Function `g`’s second parameter has a `carries_dependency` attribute,
304
  but its first parameter does not. Therefore, function `h`’s first call
305
  to `g` carries a dependency into `g`, but its second call does not. The
306
  implementation might need to insert a fence prior to the second call to
307
  `g`.
308
 
 
 
309
  ### Deprecated attribute <a id="dcl.attr.deprecated">[[dcl.attr.deprecated]]</a>
310
 
311
  The *attribute-token* `deprecated` can be used to mark names and
312
  entities whose use is still allowed, but is discouraged for some reason.
313
- in particular, `deprecated` is appropriate for names and entities that
314
- are deemed obsolescent or unsafe. It shall appear at most once in each
315
- *attribute-list*. An *attribute-argument-clause* may be present and, if
316
- present, it shall have the form:
 
 
 
317
 
318
  ``` cpp
319
  ( string-literal )
320
  ```
321
 
322
- the *string-literal* in the *attribute-argument-clause* could be used to
323
- explain the rationale for deprecation and/or to suggest a replacing
324
- entity.
325
 
326
  The attribute may be applied to the declaration of a class, a
327
- *typedef-name*, a variable, a non-static data member, a function, an
328
- enumeration, or a template specialization.
329
 
330
  A name or entity declared without the `deprecated` attribute can later
331
- be re-declared with the attribute and vice-versa. Thus, an entity
332
- initially declared without the attribute can be marked as deprecated by
333
- a subsequent redeclaration. However, after an entity is marked as
334
- deprecated, later redeclarations do not un-deprecate the entity.
 
 
 
335
  Redeclarations using different forms of the attribute (with or without
336
  the *attribute-argument-clause* or with different
337
  *attribute-argument-clause*s) are allowed.
338
 
339
- Implementations may use the `deprecated `attribute to produce a
340
- diagnostic message in case the program refers to a name or entity other
341
- than to declare it, after a declaration that specifies the attribute.
342
- The diagnostic message may include the text provided within the
343
- *attribute-argument-clause* of any `deprecated` attribute applied to the
344
- name or entity.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
345
 
 
10
  attribute-specifier-seqₒₚₜ attribute-specifier
11
  ```
12
 
13
  ``` bnf
14
  attribute-specifier:
15
+ '[' '[' attribute-using-prefixₒₚₜ attribute-list ']' ']'
16
  alignment-specifier
17
  ```
18
 
19
  ``` bnf
20
  alignment-specifier:
21
  'alignas (' type-id '...'ₒₚₜ ')'
22
  'alignas (' constant-expression '...'ₒₚₜ ')'
23
  ```
24
 
25
+ ``` bnf
26
+ attribute-using-prefix:
27
+ 'using' attribute-namespace ':'
28
+ ```
29
+
30
  ``` bnf
31
  attribute-list:
32
  attributeₒₚₜ
33
  attribute-list ',' attributeₒₚₜ
34
  attribute '...'
 
56
  identifier
57
  ```
58
 
59
  ``` bnf
60
  attribute-argument-clause:
61
+ '(' balanced-token-seqₒₚₜ ')'
62
  ```
63
 
64
  ``` bnf
65
  balanced-token-seq:
66
+ balanced-token
67
  balanced-token-seq balanced-token
68
  ```
69
 
70
  ``` bnf
71
  balanced-token:
72
+ '(' balanced-token-seqₒₚₜ ')'
73
+ '[' balanced-token-seqₒₚₜ ']'
74
+ '{' balanced-token-seqₒₚₜ '}'
75
  any *token* other than a parenthesis, a bracket, or a brace
76
  ```
77
 
78
+ If an *attribute-specifier* contains an *attribute-using-prefix*, the
79
+ *attribute-list* following that *attribute-using-prefix* shall not
80
+ contain an *attribute-scoped-token* and every *attribute-token* in that
81
+ *attribute-list* is treated as if its *identifier* were prefixed with
82
+ `N::`, where `N` is the *attribute-namespace* specified in the
83
+ *attribute-using-prefix*.
84
+
85
+ [*Note 1*: This rule imposes no constraints on how an
86
+ *attribute-using-prefix* affects the tokens in an
87
+ *attribute-argument-clause*. — *end note*]
88
+
89
+ [*Example 1*:
90
+
91
+ ``` cpp
92
+ [[using CC: opt(1), debug]] // same as [[CC::opt(1), CC::debug]]
93
+ void f() {}
94
+ [[using CC: opt(1)]] [[CC::debug]] // same as [[CC::opt(1)]] [[CC::debug]]
95
+ void g() {}
96
+ [[using CC: CC::opt(1)]] // error: cannot combine using and scoped attribute token
97
+ void h() {}
98
+ ```
99
+
100
+ — *end example*]
101
+
102
+ [*Note 2*: For each individual attribute, the form of the
103
+ *balanced-token-seq* will be specified. — *end note*]
104
 
105
  In an *attribute-list*, an ellipsis may appear only if that
106
  *attribute*’s specification permits it. An *attribute* followed by an
107
  ellipsis is a pack expansion ([[temp.variadic]]). An
108
  *attribute-specifier* that contains no *attribute*s has no effect. The
109
+ order in which the *attribute-token*s appear in an *attribute-list* is
110
  not significant. If a keyword ([[lex.key]]) or an alternative token (
111
  [[lex.digraph]]) that satisfies the syntactic requirements of an
112
  *identifier* ([[lex.name]]) is contained in an *attribute-token*, it is
113
  considered an identifier. No name lookup ([[basic.lookup]]) is
114
  performed on any of the identifiers contained in an *attribute-token*.
115
  The *attribute-token* determines additional requirements on the
116
+ *attribute-argument-clause* (if any).
 
 
 
 
117
 
118
  Each *attribute-specifier-seq* is said to *appertain* to some entity or
119
  statement, identified by the syntactic context where it appears (Clause 
120
  [[stmt.stmt]], Clause  [[dcl.dcl]], Clause  [[dcl.decl]]). If an
121
  *attribute-specifier-seq* that appertains to some entity or statement
122
+ contains an *attribute* or *alignment-specifier* that is not allowed to
123
+ apply to that entity or statement, the program is ill-formed. If an
124
+ *attribute-specifier-seq* appertains to a friend declaration (
125
+ [[class.friend]]), that declaration shall be a definition. No
126
+ *attribute-specifier-seq* shall appertain to an explicit instantiation (
127
+ [[temp.explicit]]).
128
 
129
+ For an *attribute-token* (including an *attribute-scoped-token*) not
130
+ specified in this International Standard, the behavior is
131
+ *implementation-defined*. Any *attribute-token* that is not recognized
132
+ by the implementation is ignored.
133
+
134
+ [*Note 3*: Each implementation should choose a distinctive name for the
135
+ *attribute-namespace* in an *attribute-scoped-token*. — *end note*]
136
 
137
  Two consecutive left square bracket tokens shall appear only when
138
+ introducing an *attribute-specifier* or within the *balanced-token-seq*
139
+ of an *attribute-argument-clause*.
140
+
141
+ [*Note 4*: If two consecutive left square brackets appear where an
142
+ *attribute-specifier* is not allowed, the program is ill-formed even if
143
+ the brackets match an alternative grammar production. — *end note*]
144
+
145
+ [*Example 2*:
146
 
147
  ``` cpp
148
  int p[10];
149
  void f() {
150
  int x = 42, y[5];
151
+ int(p[[x] { return x; }()]); // error: invalid attribute on a nested declarator-id and
152
+ // not a function-style cast of an element of p.
153
+ y[[] { return 2; }()] = 2; // error even though attributes are not allowed in this context.
154
+ int i [[vendor::attr([[]])]]; // well-formed implementation-defined attribute.
 
155
  }
156
  ```
157
 
158
+ — *end example*]
159
+
160
  ### Alignment specifier <a id="dcl.align">[[dcl.align]]</a>
161
 
162
  An *alignment-specifier* may be applied to a variable or to a class data
163
  member, but it shall not be applied to a bit-field, a function
164
+ parameter, or an *exception-declaration* ([[except.handle]]). An
 
165
  *alignment-specifier* may also be applied to the declaration or
166
  definition of a class (in an *elaborated-type-specifier* (
167
  [[dcl.type.elab]]) or *class-head* (Clause  [[class]]), respectively)
168
  and to the declaration or definition of an enumeration (in an
169
  *opaque-enum-declaration* or *enum-head*, respectively ([[dcl.enum]])).
 
172
 
173
  When the *alignment-specifier* is of the form `alignas(`
174
  *constant-expression* `)`:
175
 
176
  - the *constant-expression* shall be an integral constant expression
177
+ - if the constant expression does not evaluate to an alignment value (
178
+ [[basic.align]]), or evaluates to an extended alignment and the
 
 
 
 
 
 
179
  implementation does not support that alignment in the context of the
180
+ declaration, the program is ill-formed.
 
 
 
181
 
182
+ An *alignment-specifier* of the form `alignas(` *type-id* `)` has the
183
+ same effect as `alignas({}alignof(` *type-id* `))` ([[expr.alignof]]).
 
184
 
185
+ The alignment requirement of an entity is the strictest nonzero
186
+ alignment specified by its *alignment-specifier*s, if any; otherwise,
187
+ the *alignment-specifier*s have no effect.
188
 
189
  The combined effect of all *alignment-specifier*s in a declaration shall
190
  not specify an alignment that is less strict than the alignment that
191
  would be required for the entity being declared if all
192
+ *alignment-specifier*s appertaining to that entity were omitted.
193
+
194
+ [*Example 1*:
195
+
196
+ ``` cpp
197
+ struct alignas(8) S {};
198
+ struct alignas(1) U {
199
+ S s;
200
+ }; // error: U specifies an alignment that is less strict than if the alignas(1) were omitted.
201
+ ```
202
+
203
+ — *end example*]
204
 
205
  If the defining declaration of an entity has an *alignment-specifier*,
206
  any non-defining declaration of that entity shall either specify
207
  equivalent alignment or have no *alignment-specifier*. Conversely, if
208
  any declaration of an entity has an *alignment-specifier*, every
209
  defining declaration of that entity shall specify an equivalent
210
  alignment. No diagnostic is required if declarations of an entity have
211
  different *alignment-specifier*s in different translation units.
212
 
213
+ [*Example 2*:
214
+
215
  ``` cpp
216
  // Translation unit #1:
217
+ struct S { int x; } s, *p = &s;
218
 
219
  // Translation unit #2:
220
+ struct alignas(16) S; // error: definition of S lacks alignment, no diagnostic required
221
+ extern S* p;
222
  ```
223
 
224
+ — *end example*]
225
+
226
+ [*Example 3*:
227
+
228
  An aligned buffer with an alignment requirement of `A` and holding `N`
229
+ elements of type `T` can be declared as:
 
230
 
231
  ``` cpp
232
  alignas(T) alignas(A) T buffer[N];
233
  ```
234
 
235
  Specifying `alignas(T)` ensures that the final requested alignment will
236
  not be weaker than `alignof(T)`, and therefore the program will not be
237
  ill-formed.
238
 
239
+ — *end example*]
240
+
241
+ [*Example 4*:
242
+
243
  ``` cpp
244
  alignas(double) void f(); // error: alignment applied to function
245
  alignas(double) unsigned char c[sizeof(double)]; // array of characters, suitably aligned for a double
246
  extern unsigned char c[sizeof(double)]; // no alignas necessary
247
  alignas(float)
248
  extern unsigned char c[sizeof(double)]; // error: different alignment in declaration
249
  ```
250
 
251
+ *end example*]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
252
 
253
  ### Carries dependency attribute <a id="dcl.attr.depend">[[dcl.attr.depend]]</a>
254
 
255
  The *attribute-token* `carries_dependency` specifies dependency
256
  propagation into and out of functions. It shall appear at most once in
 
273
  attribute for that parameter. If a function or one of its parameters is
274
  declared with the `carries_dependency` attribute in its first
275
  declaration in one translation unit and the same function or one of its
276
  parameters is declared without the `carries_dependency` attribute in its
277
  first declaration in another translation unit, the program is
278
+ ill-formed, no diagnostic required.
279
 
280
+ [*Note 1*: The `carries_dependency` attribute does not change the
281
+ meaning of the program, but may result in generation of more efficient
282
+ code. — *end note*]
283
+
284
+ [*Example 1*:
285
 
286
  ``` cpp
287
  /* Translation unit A. */
288
 
289
  struct foo { int* a; int* b; };
 
324
  but its first parameter does not. Therefore, function `h`’s first call
325
  to `g` carries a dependency into `g`, but its second call does not. The
326
  implementation might need to insert a fence prior to the second call to
327
  `g`.
328
 
329
+ — *end example*]
330
+
331
  ### Deprecated attribute <a id="dcl.attr.deprecated">[[dcl.attr.deprecated]]</a>
332
 
333
  The *attribute-token* `deprecated` can be used to mark names and
334
  entities whose use is still allowed, but is discouraged for some reason.
335
+
336
+ [*Note 1*: In particular, `deprecated` is appropriate for names and
337
+ entities that are deemed obsolescent or unsafe. — *end note*]
338
+
339
+ It shall appear at most once in each *attribute-list*. An
340
+ *attribute-argument-clause* may be present and, if present, it shall
341
+ have the form:
342
 
343
  ``` cpp
344
  ( string-literal )
345
  ```
346
 
347
+ [*Note 2*: The *string-literal* in the *attribute-argument-clause*
348
+ could be used to explain the rationale for deprecation and/or to suggest
349
+ a replacing entity. — *end note*]
350
 
351
  The attribute may be applied to the declaration of a class, a
352
+ *typedef-name*, a variable, a non-static data member, a function, a
353
+ namespace, an enumeration, an enumerator, or a template specialization.
354
 
355
  A name or entity declared without the `deprecated` attribute can later
356
+ be redeclared with the attribute and vice-versa.
357
+
358
+ [*Note 3*: Thus, an entity initially declared without the attribute can
359
+ be marked as deprecated by a subsequent redeclaration. However, after an
360
+ entity is marked as deprecated, later redeclarations do not un-deprecate
361
+ the entity. — *end note*]
362
+
363
  Redeclarations using different forms of the attribute (with or without
364
  the *attribute-argument-clause* or with different
365
  *attribute-argument-clause*s) are allowed.
366
 
367
+ [*Note 4*: Implementations may use the `deprecated` attribute to
368
+ produce a diagnostic message in case the program refers to a name or
369
+ entity other than to declare it, after a declaration that specifies the
370
+ attribute. The diagnostic message may include the text provided within
371
+ the *attribute-argument-clause* of any `deprecated` attribute applied to
372
+ the name or entity. — *end note*]
373
+
374
+ ### Fallthrough attribute <a id="dcl.attr.fallthrough">[[dcl.attr.fallthrough]]</a>
375
+
376
+ The *attribute-token* `fallthrough` may be applied to a null statement (
377
+ [[stmt.expr]]); such a statement is a fallthrough statement. The
378
+ *attribute-token* `fallthrough` shall appear at most once in each
379
+ *attribute-list* and no *attribute-argument-clause* shall be present. A
380
+ fallthrough statement may only appear within an enclosing `switch`
381
+ statement ([[stmt.switch]]). The next statement that would be executed
382
+ after a fallthrough statement shall be a labeled statement whose label
383
+ is a case label or default label for the same `switch` statement. The
384
+ program is ill-formed if there is no such statement.
385
+
386
+ [*Note 1*: The use of a fallthrough statement is intended to suppress a
387
+ warning that an implementation might otherwise issue for a case or
388
+ default label that is reachable from another case or default label along
389
+ some path of execution. Implementations are encouraged to issue a
390
+ warning if a fallthrough statement is not dynamically
391
+ reachable. — *end note*]
392
+
393
+ [*Example 1*:
394
+
395
+ ``` cpp
396
+ void f(int n) {
397
+ void g(), h(), i();
398
+ switch (n) {
399
+ case 1:
400
+ case 2:
401
+ g();
402
+ [[fallthrough]];
403
+ case 3: // warning on fallthrough discouraged
404
+ h();
405
+ case 4: // implementation may warn on fallthrough
406
+ i();
407
+ [[fallthrough]]; // ill-formed
408
+ }
409
+ }
410
+ ```
411
+
412
+ — *end example*]
413
+
414
+ ### Maybe unused attribute <a id="dcl.attr.unused">[[dcl.attr.unused]]</a>
415
+
416
+ The *attribute-token* `maybe_unused` indicates that a name or entity is
417
+ possibly intentionally unused. It shall appear at most once in each
418
+ *attribute-list* and no *attribute-argument-clause* shall be present.
419
+
420
+ The attribute may be applied to the declaration of a class, a
421
+ *typedef-name*, a variable, a non-static data member, a function, an
422
+ enumeration, or an enumerator.
423
+
424
+ [*Note 1*: For an entity marked `maybe_unused`, implementations are
425
+ encouraged not to emit a warning that the entity is unused, or that the
426
+ entity is used despite the presence of the attribute. — *end note*]
427
+
428
+ A name or entity declared without the `maybe_unused` attribute can later
429
+ be redeclared with the attribute and vice versa. An entity is considered
430
+ marked after the first declaration that marks it.
431
+
432
+ [*Example 1*:
433
+
434
+ ``` cpp
435
+ [[maybe_unused]] void f([[maybe_unused]] bool thing1,
436
+ [[maybe_unused]] bool thing2) {
437
+ [[maybe_unused]] bool b = thing1 && thing2;
438
+ assert(b);
439
+ }
440
+ ```
441
+
442
+ Implementations are encouraged not to warn that `b` is unused, whether
443
+ or not `NDEBUG` is defined.
444
+
445
+ — *end example*]
446
+
447
+ ### Nodiscard attribute <a id="dcl.attr.nodiscard">[[dcl.attr.nodiscard]]</a>
448
+
449
+ The *attribute-token* `nodiscard` may be applied to the *declarator-id*
450
+ in a function declaration or to the declaration of a class or
451
+ enumeration. It shall appear at most once in each *attribute-list* and
452
+ no *attribute-argument-clause* shall be present.
453
+
454
+ [*Note 1*: A nodiscard call is a function call expression that calls a
455
+ function previously declared `nodiscard`, or whose return type is a
456
+ possibly cv-qualified class or enumeration type marked `nodiscard`.
457
+ Appearance of a nodiscard call as a potentially-evaluated
458
+ discarded-value expression (Clause  [[expr]]) is discouraged unless
459
+ explicitly cast to `void`. Implementations are encouraged to issue a
460
+ warning in such cases. This is typically because discarding the return
461
+ value of a nodiscard call has surprising consequences. — *end note*]
462
+
463
+ [*Example 1*:
464
+
465
+ ``` cpp
466
+ struct [[nodiscard]] error_info { ... };
467
+ error_info enable_missile_safety_mode();
468
+ void launch_missiles();
469
+ void test_missiles() {
470
+ enable_missile_safety_mode(); // warning encouraged
471
+ launch_missiles();
472
+ }
473
+ error_info &foo();
474
+ void f() { foo(); } // warning not encouraged: not a nodiscard call, because neither
475
+ // the (reference) return type nor the function is declared nodiscard
476
+ ```
477
+
478
+ — *end example*]
479
+
480
+ ### Noreturn attribute <a id="dcl.attr.noreturn">[[dcl.attr.noreturn]]</a>
481
+
482
+ The *attribute-token* `noreturn` specifies that a function does not
483
+ return. It shall appear at most once in each *attribute-list* and no
484
+ *attribute-argument-clause* shall be present. The attribute may be
485
+ applied to the *declarator-id* in a function declaration. The first
486
+ declaration of a function shall specify the `noreturn` attribute if any
487
+ declaration of that function specifies the `noreturn` attribute. If a
488
+ function is declared with the `noreturn` attribute in one translation
489
+ unit and the same function is declared without the `noreturn` attribute
490
+ in another translation unit, the program is ill-formed, no diagnostic
491
+ required.
492
+
493
+ If a function `f` is called where `f` was previously declared with the
494
+ `noreturn` attribute and `f` eventually returns, the behavior is
495
+ undefined.
496
+
497
+ [*Note 1*: The function may terminate by throwing an
498
+ exception. — *end note*]
499
+
500
+ [*Note 2*: Implementations are encouraged to issue a warning if a
501
+ function marked `[[noreturn]]` might return. — *end note*]
502
+
503
+ [*Example 1*:
504
+
505
+ ``` cpp
506
+ [[ noreturn ]] void f() {
507
+ throw "error"; // OK
508
+ }
509
+
510
+ [[ noreturn ]] void q(int i) { // behavior is undefined if called with an argument <= 0
511
+ if (i > 0)
512
+ throw "positive";
513
+ }
514
+ ```
515
+
516
+ — *end example*]
517