- 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 |
-
|
| 74 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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-
|
| 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).
|
| 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
|
| 98 |
-
statement, the program is ill-formed. If an
|
| 99 |
-
appertains to a friend declaration (
|
| 100 |
-
shall be a definition. No
|
| 101 |
-
an explicit instantiation (
|
|
|
|
| 102 |
|
| 103 |
-
For an *attribute-token*
|
| 104 |
-
the behavior is
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 105 |
|
| 106 |
Two consecutive left square bracket tokens shall appear only when
|
| 107 |
-
introducing an *attribute-specifier*
|
| 108 |
-
|
| 109 |
-
|
| 110 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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 |
-
//
|
| 118 |
-
|
| 119 |
-
|
| 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]])
|
| 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
|
| 143 |
-
|
| 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 |
-
|
| 157 |
-
|
| 158 |
-
[[expr.alignof]]).
|
| 159 |
|
| 160 |
-
|
| 161 |
-
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
|
| 167 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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
|
| 183 |
-
extern S* p;
|
| 184 |
```
|
| 185 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 186 |
An aligned buffer with an alignment requirement of `A` and holding `N`
|
| 187 |
-
elements of type `T`
|
| 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 |
-
|
| 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
|
| 262 |
|
| 263 |
-
The `carries_dependency` attribute does not change the
|
| 264 |
-
program, but may result in generation of more efficient
|
|
|
|
|
|
|
|
|
|
| 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 |
-
|
| 314 |
-
|
| 315 |
-
|
| 316 |
-
|
|
|
|
|
|
|
|
|
|
| 317 |
|
| 318 |
``` cpp
|
| 319 |
( string-literal )
|
| 320 |
```
|
| 321 |
|
| 322 |
-
|
| 323 |
-
explain the rationale for deprecation and/or to suggest
|
| 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,
|
| 328 |
-
enumeration, or a template specialization.
|
| 329 |
|
| 330 |
A name or entity declared without the `deprecated` attribute can later
|
| 331 |
-
be
|
| 332 |
-
|
| 333 |
-
|
| 334 |
-
|
|
|
|
|
|
|
|
|
|
| 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
|
| 340 |
-
diagnostic message in case the program refers to a name or
|
| 341 |
-
than to declare it, after a declaration that specifies the
|
| 342 |
-
The diagnostic message may include the text provided within
|
| 343 |
-
*attribute-argument-clause* of any `deprecated` attribute applied to
|
| 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 |
|