882 lines
52 KiB
Markdown
882 lines
52 KiB
Markdown
[dcl.attr]
|
||
|
||
# 9 Declarations [[dcl]](./#dcl)
|
||
|
||
## 9.13 Attributes [dcl.attr]
|
||
|
||
### [9.13.1](#grammar) Attribute syntax and semantics [[dcl.attr.grammar]](dcl.attr.grammar)
|
||
|
||
[1](#grammar-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L9349)
|
||
|
||
Attributes and annotations specify additional information for various source constructs
|
||
such as types, variables, names, contract assertions, blocks, or translation units[.](#grammar-1.sentence-1)
|
||
|
||
[attribute-specifier-seq:](#nt:attribute-specifier-seq "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]")
|
||
[*attribute-specifier*](#nt:attribute-specifier "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") [*attribute-specifier-seq*](#nt:attribute-specifier-seq "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]")opt
|
||
|
||
[attribute-specifier:](#nt:attribute-specifier "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]")
|
||
[ [ [*attribute-using-prefix*](#nt:attribute-using-prefix "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]")opt [*attribute-list*](#nt:attribute-list "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") ] ]
|
||
[ [ [*annotation-list*](#nt:annotation-list "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") ] ]
|
||
[*alignment-specifier*](#nt:alignment-specifier "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]")
|
||
|
||
[alignment-specifier:](#nt:alignment-specifier "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]")
|
||
alignas ( [*type-id*](dcl.name#nt:type-id "9.3.2 Type names [dcl.name]") ...opt )
|
||
alignas ( [*constant-expression*](expr.const#nt:constant-expression "7.7 Constant expressions [expr.const]") ...opt )
|
||
|
||
[attribute-using-prefix:](#nt:attribute-using-prefix "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]")
|
||
using [*attribute-namespace*](#nt:attribute-namespace "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") :
|
||
|
||
[attribute-list:](#nt:attribute-list "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]")
|
||
[*attribute*](#nt:attribute "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]")opt
|
||
[*attribute-list*](#nt:attribute-list "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") , [*attribute*](#nt:attribute "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]")opt
|
||
[*attribute*](#nt:attribute "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") ...
|
||
[*attribute-list*](#nt:attribute-list "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") , [*attribute*](#nt:attribute "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") ...
|
||
|
||
[annotation-list:](#nt:annotation-list "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]")
|
||
[*annotation*](#nt:annotation "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") ...opt
|
||
[*annotation-list*](#nt:annotation-list "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") , [*annotation*](#nt:annotation "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") ...opt
|
||
|
||
[attribute:](#nt:attribute "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]")
|
||
[*attribute-token*](#nt:attribute-token "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") [*attribute-argument-clause*](#nt:attribute-argument-clause "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]")opt
|
||
|
||
[annotation:](#nt:annotation "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]")
|
||
= [*constant-expression*](expr.const#nt:constant-expression "7.7 Constant expressions [expr.const]")
|
||
|
||
[attribute-token:](#nt:attribute-token "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]")
|
||
[*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]")
|
||
[*attribute-scoped-token*](#nt:attribute-scoped-token "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]")
|
||
|
||
[attribute-scoped-token:](#nt:attribute-scoped-token "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]")
|
||
[*attribute-namespace*](#nt:attribute-namespace "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") :: [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]")
|
||
|
||
[attribute-namespace:](#nt:attribute-namespace "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]")
|
||
[*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]")
|
||
|
||
[attribute-argument-clause:](#nt:attribute-argument-clause "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]")
|
||
( [*balanced-token-seq*](#nt:balanced-token-seq "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]")opt )
|
||
|
||
[balanced-token-seq:](#nt:balanced-token-seq "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]")
|
||
[*balanced-token*](#nt:balanced-token "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") [*balanced-token-seq*](#nt:balanced-token-seq "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]")opt
|
||
|
||
[balanced-token:](#nt:balanced-token "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]")
|
||
( [*balanced-token-seq*](#nt:balanced-token-seq "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]")opt )
|
||
[ [*balanced-token-seq*](#nt:balanced-token-seq "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]")opt ]
|
||
{ [*balanced-token-seq*](#nt:balanced-token-seq "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]")opt }
|
||
[: [*balanced-token-seq*](#nt:balanced-token-seq "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]")opt :]
|
||
any [*token*](lex.token#nt:token "5.10 Tokens [lex.token]") other than (, ), [, ], {, }, [:, or :]
|
||
|
||
[2](#grammar-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L9437)
|
||
|
||
If an [*attribute-specifier*](#nt:attribute-specifier "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") contains an [*attribute-using-prefix*](#nt:attribute-using-prefix "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]"),
|
||
the [*attribute-list*](#nt:attribute-list "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") following that [*attribute-using-prefix*](#nt:attribute-using-prefix "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") shall not contain an [*attribute-scoped-token*](#nt:attribute-scoped-token "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") and every [*attribute-token*](#nt:attribute-token "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") in that [*attribute-list*](#nt:attribute-list "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") is treated as if
|
||
its [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]") were prefixed with N::,
|
||
where N is the [*attribute-namespace*](#nt:attribute-namespace "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") specified in the [*attribute-using-prefix*](#nt:attribute-using-prefix "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]")[.](#grammar-2.sentence-1)
|
||
|
||
[*Note [1](#grammar-note-1)*:
|
||
|
||
This rule imposes no constraints on how
|
||
an [*attribute-using-prefix*](#nt:attribute-using-prefix "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") affects the tokens in an [*attribute-argument-clause*](#nt:attribute-argument-clause "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]")[.](#grammar-2.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
[*Example [1](#grammar-example-1)*: [[using CC: opt(1), debug]] // same as [[CC::opt(1), CC::debug]]void f() {}[[using CC: opt(1)]] [[CC::debug]] // same as [[CC::opt(1)]] [[CC::debug]]void g() {}[[using CC: CC::opt(1)]] // error: cannot combine using and scoped attribute tokenvoid h() {} â *end example*]
|
||
|
||
[3](#grammar-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L9463)
|
||
|
||
[*Note [2](#grammar-note-2)*:
|
||
|
||
For each individual attribute, the form of the[*balanced-token-seq*](#nt:balanced-token-seq "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") will be specified[.](#grammar-3.sentence-1)
|
||
|
||
â *end note*]
|
||
|
||
[4](#grammar-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L9469)
|
||
|
||
In an [*attribute-list*](#nt:attribute-list "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]"), an ellipsis may appear only if that[*attribute*](#nt:attribute "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]")'s specification permits it[.](#grammar-4.sentence-1)
|
||
|
||
An [*attribute*](#nt:attribute "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") followed
|
||
by an ellipsis is a [pack expansion](temp.variadic#def:pack_expansion "13.7.4 Variadic templates [temp.variadic]")[.](#grammar-4.sentence-2)
|
||
|
||
An [*attribute-specifier*](#nt:attribute-specifier "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") that contains
|
||
an [*attribute-list*](#nt:attribute-list "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") with no [*attribute*](#nt:attribute "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]")*s* and no [*alignment-specifier*](#nt:alignment-specifier "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") has no effect[.](#grammar-4.sentence-3)
|
||
|
||
The order in which the [*attribute-token*](#nt:attribute-token "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]")*s* appear in an[*attribute-list*](#nt:attribute-list "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") is not significant[.](#grammar-4.sentence-4)
|
||
|
||
If a[keyword](lex.key "5.12 Keywords [lex.key]") or an [alternative token](lex.digraph "5.9 Alternative tokens [lex.digraph]") that satisfies the syntactic requirements
|
||
of an [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]") ([[lex.name]](lex.name "5.11 Identifiers")) is
|
||
contained in
|
||
an [*attribute-token*](#nt:attribute-token "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]"), it is considered an identifier[.](#grammar-4.sentence-5)
|
||
|
||
No[name lookup](basic.lookup "6.5 Name lookup [basic.lookup]") is performed on any of the identifiers contained in an[*attribute-token*](#nt:attribute-token "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]")[.](#grammar-4.sentence-6)
|
||
|
||
The [*attribute-token*](#nt:attribute-token "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") determines additional
|
||
requirements on the [*attribute-argument-clause*](#nt:attribute-argument-clause "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") (if any)[.](#grammar-4.sentence-7)
|
||
|
||
[5](#grammar-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L9488)
|
||
|
||
An [*annotation*](#nt:annotation "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") followed by an ellipsis
|
||
is a pack expansion ([[temp.variadic]](temp.variadic "13.7.4 Variadic templates"))[.](#grammar-5.sentence-1)
|
||
|
||
[6](#grammar-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L9492)
|
||
|
||
Each [*attribute-specifier-seq*](#nt:attribute-specifier-seq "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") is said to [*appertain*](#def:appertain "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") to some entity or
|
||
statement, identified by the syntactic context
|
||
where it appears ([[stmt]](stmt "8 Statements"), [[dcl]](dcl "9 Declarations"), [[dcl.decl]](dcl.decl "9.3 Declarators"))[.](#grammar-6.sentence-1)
|
||
|
||
If an [*attribute-specifier-seq*](#nt:attribute-specifier-seq "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") that appertains to some
|
||
entity or statement contains an [*attribute*](#nt:attribute "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") or [*alignment-specifier*](#nt:alignment-specifier "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") that
|
||
is not allowed to apply to that
|
||
entity or statement, the program is ill-formed[.](#grammar-6.sentence-2)
|
||
|
||
If an [*attribute-specifier-seq*](#nt:attribute-specifier-seq "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") appertains to a friend declaration ([[class.friend]](class.friend "11.8.4 Friends")), that declaration shall be a
|
||
definition[.](#grammar-6.sentence-3)
|
||
|
||
[*Note [3](#grammar-note-3)*:
|
||
|
||
An [*attribute-specifier-seq*](#nt:attribute-specifier-seq "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") cannot appertain to
|
||
an explicit instantiation ([[temp.explicit]](temp.explicit "13.9.3 Explicit instantiation"))[.](#grammar-6.sentence-4)
|
||
|
||
â *end note*]
|
||
|
||
[7](#grammar-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L9507)
|
||
|
||
For an [*attribute-token*](#nt:attribute-token "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") (including an [*attribute-scoped-token*](#nt:attribute-scoped-token "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]"))
|
||
not specified in this document, the
|
||
behavior is implementation-defined;
|
||
any such [*attribute-token*](#nt:attribute-token "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") that is not recognized by the implementation
|
||
is ignored[.](#grammar-7.sentence-1)
|
||
|
||
[*Note [4](#grammar-note-4)*:
|
||
|
||
A program is ill-formed if it contains an [*attribute*](#nt:attribute "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") specified in [dcl.attr] that violates
|
||
the rules specifying to which entity or statement the attribute can apply or
|
||
the syntax rules for the attribute's [*attribute-argument-clause*](#nt:attribute-argument-clause "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]"), if any[.](#grammar-7.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
[*Note [5](#grammar-note-5)*:
|
||
|
||
The [*attribute*](#nt:attribute "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]")*s* specified in [dcl.attr]
|
||
have optional semantics:
|
||
given a well-formed program,
|
||
removing all instances of any one of those [*attribute*](#nt:attribute "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]")*s* results in a program whose set of possible executions ([[intro.abstract]](intro.abstract "4.1.2 Abstract machine"))
|
||
for a given input is
|
||
a subset of those of the original program for the same input,
|
||
absent implementation-defined guarantees
|
||
with respect to that [*attribute*](#nt:attribute "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]")[.](#grammar-7.sentence-3)
|
||
|
||
â *end note*]
|
||
|
||
An [*attribute-token*](#nt:attribute-token "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") is reserved for future standardization if
|
||
|
||
- [(7.1)](#grammar-7.1)
|
||
|
||
it is not an [*attribute-scoped-token*](#nt:attribute-scoped-token "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") and
|
||
is not specified in this document, or
|
||
|
||
- [(7.2)](#grammar-7.2)
|
||
|
||
it is an [*attribute-scoped-token*](#nt:attribute-scoped-token "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") and
|
||
its [*attribute-namespace*](#nt:attribute-namespace "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") isstd followed by zero or more digits[.](#grammar-7.sentence-4)
|
||
|
||
Each implementation should choose a distinctive name for the[*attribute-namespace*](#nt:attribute-namespace "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") in an [*attribute-scoped-token*](#nt:attribute-scoped-token "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]")[.](#grammar-7.sentence-5)
|
||
|
||
[8](#grammar-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L9542)
|
||
|
||
Two consecutive left square bracket tokens shall appear only
|
||
when introducing an [*attribute-specifier*](#nt:attribute-specifier "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") or
|
||
within the [*balanced-token-seq*](#nt:balanced-token-seq "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") of
|
||
an [*attribute-argument-clause*](#nt:attribute-argument-clause "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]")[.](#grammar-8.sentence-1)
|
||
|
||
[*Note [6](#grammar-note-6)*:
|
||
|
||
If two consecutive left square brackets appear
|
||
where an [*attribute-specifier*](#nt:attribute-specifier "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") is not allowed, the program is ill-formed even
|
||
if the brackets match an alternative grammar production[.](#grammar-8.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
[*Example [2](#grammar-example-2)*: int p[10];void f() {int x = 42, y[5]; int(p[[x] { return x; }()]); // error: invalid attribute on a nested [*declarator-id*](dcl.decl.general#nt:declarator-id "9.3.1 General [dcl.decl.general]") and// not a function-style cast of an element of p. y[[] { return 2; }()] = 2; // error even though attributes are not allowed in this context.int i [[vendor::attr([[]])]]; // well-formed implementation-defined attribute.} â *end example*]
|
||
|
||
### [9.13.2](#dcl.align) Alignment specifier [[dcl.align]](dcl.align)
|
||
|
||
[1](#dcl.align-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L9569)
|
||
|
||
An [*alignment-specifier*](#nt:alignment-specifier "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") may be applied to a variable
|
||
or to a class data member, but it shall not be applied to a bit-field, a function
|
||
parameter, or an [*exception-declaration*](except.pre#nt:exception-declaration "14.1 Preamble [except.pre]") ([[except.handle]](except.handle "14.4 Handling an exception"))[.](#dcl.align-1.sentence-1)
|
||
|
||
An [*alignment-specifier*](#nt:alignment-specifier "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") may also be applied to the declaration
|
||
of a class (in an[*elaborated-type-specifier*](dcl.type.elab#nt:elaborated-type-specifier "9.2.9.5 Elaborated type specifiers [dcl.type.elab]") ([[dcl.type.elab]](dcl.type.elab "9.2.9.5 Elaborated type specifiers")) or[*class-head*](class.pre#nt:class-head "11.1 Preamble [class.pre]") ([[class]](class "11 Classes")), respectively)[.](#dcl.align-1.sentence-2)
|
||
|
||
An [*alignment-specifier*](#nt:alignment-specifier "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") with an ellipsis is a pack expansion ([[temp.variadic]](temp.variadic "13.7.4 Variadic templates"))[.](#dcl.align-1.sentence-3)
|
||
|
||
[2](#dcl.align-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L9580)
|
||
|
||
When the [*alignment-specifier*](#nt:alignment-specifier "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") is of the formalignas( [*constant-expression*](expr.const#nt:constant-expression "7.7 Constant expressions [expr.const]") ):
|
||
|
||
- [(2.1)](#dcl.align-2.1)
|
||
|
||
the [*constant-expression*](expr.const#nt:constant-expression "7.7 Constant expressions [expr.const]") shall be an integral constant expression
|
||
|
||
- [(2.2)](#dcl.align-2.2)
|
||
|
||
if the constant expression does not evaluate to an alignment
|
||
value ([[basic.align]](basic.align "6.8.3 Alignment")), or evaluates to an extended alignment and
|
||
the implementation does not support that alignment in the context of the
|
||
declaration, the program is ill-formed[.](#dcl.align-2.sentence-1)
|
||
|
||
[3](#dcl.align-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L9592)
|
||
|
||
An [*alignment-specifier*](#nt:alignment-specifier "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") of the formalignas( [*type-id*](dcl.name#nt:type-id "9.3.2 Type names [dcl.name]") ) has the same
|
||
effect as alignas([alignof](expr.alignof "7.6.2.6 Alignof [expr.alignof]")( [*type-id*](dcl.name#nt:type-id "9.3.2 Type names [dcl.name]") ))[.](#dcl.align-3.sentence-1)
|
||
|
||
[4](#dcl.align-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L9597)
|
||
|
||
The alignment requirement of an entity is the strictest nonzero alignment
|
||
specified by its [*alignment-specifier*](#nt:alignment-specifier "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]")*s*, if any;
|
||
otherwise, the [*alignment-specifier*](#nt:alignment-specifier "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]")*s* have no effect[.](#dcl.align-4.sentence-1)
|
||
|
||
[5](#dcl.align-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L9602)
|
||
|
||
The combined effect of all [*alignment-specifier*](#nt:alignment-specifier "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]")*s* in a declaration shall not
|
||
specify an alignment that is less strict than the alignment that would
|
||
be required for the entity being declared if all [*alignment-specifier*](#nt:alignment-specifier "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]")*s* appertaining to that entity
|
||
were omitted[.](#dcl.align-5.sentence-1)
|
||
|
||
[*Example [1](#dcl.align-example-1)*: struct alignas(8) S {};struct alignas(1) U { S s;}; // error: U specifies an alignment that is less strict than if the alignas(1) were omitted. â *end example*]
|
||
|
||
[6](#dcl.align-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L9617)
|
||
|
||
If the defining declaration of an entity has an[*alignment-specifier*](#nt:alignment-specifier "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]"), any non-defining
|
||
declaration of that entity shall either specify equivalent alignment or have no[*alignment-specifier*](#nt:alignment-specifier "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]")[.](#dcl.align-6.sentence-1)
|
||
|
||
Conversely, if any declaration of an entity has an[*alignment-specifier*](#nt:alignment-specifier "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]"),
|
||
every defining
|
||
declaration of that entity shall specify an equivalent alignment[.](#dcl.align-6.sentence-2)
|
||
|
||
No diagnostic is required if declarations of an entity have
|
||
different [*alignment-specifier*](#nt:alignment-specifier "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]")*s* in different translation units[.](#dcl.align-6.sentence-3)
|
||
|
||
[*Example [2](#dcl.align-example-2)*: // Translation unit #1:struct S { int x; } s, *p = &s;
|
||
|
||
// Translation unit #2:struct alignas(16) S; // ill-formed, no diagnostic required: definition of S lacks alignmentextern S* p; â *end example*]
|
||
|
||
[7](#dcl.align-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L9640)
|
||
|
||
[*Example [3](#dcl.align-example-3)*:
|
||
|
||
An aligned buffer with an alignment requirement
|
||
of A and holding N elements of type T can be declared as:alignas(T) alignas(A) T buffer[N];
|
||
|
||
Specifying alignas(T) ensures
|
||
that the final requested alignment will not be weaker than alignof(T),
|
||
and therefore the program will not be ill-formed[.](#dcl.align-7.sentence-2)
|
||
|
||
â *end example*]
|
||
|
||
[8](#dcl.align-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L9653)
|
||
|
||
[*Example [4](#dcl.align-example-4)*: alignas(double) void f(); // error: alignment applied to functionalignas(double) unsigned char c[sizeof(double)]; // array of characters, suitably aligned for a doubleextern unsigned char c[sizeof(double)]; // no alignas necessaryalignas(float)extern unsigned char c[sizeof(double)]; // error: different alignment in declaration â *end example*]
|
||
|
||
### [9.13.3](#assume) Assumption attribute [[dcl.attr.assume]](dcl.attr.assume)
|
||
|
||
[1](#assume-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L9666)
|
||
|
||
The [*attribute-token*](#nt:attribute-token "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") assume may be applied to a null statement;
|
||
such a statement is an [*assumption*](#def:assumption "9.13.3 Assumption attribute [dcl.attr.assume]")[.](#assume-1.sentence-1)
|
||
|
||
An [*attribute-argument-clause*](#nt:attribute-argument-clause "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") shall be present and
|
||
shall have the form:
|
||
|
||
( [*conditional-expression*](expr.cond#nt:conditional-expression "7.6.16 Conditional operator [expr.cond]") )
|
||
|
||
The expression is contextually converted to bool ([[conv.general]](conv.general "7.3.1 General"))[.](#assume-1.sentence-2)
|
||
|
||
The expression is not evaluated[.](#assume-1.sentence-3)
|
||
|
||
If the converted expression would evaluate to true at the point where the assumption appears,
|
||
the assumption has no effect[.](#assume-1.sentence-4)
|
||
|
||
Otherwise,
|
||
evaluation of the assumption has runtime-undefined behavior[.](#assume-1.sentence-5)
|
||
|
||
[2](#assume-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L9682)
|
||
|
||
[*Note [1](#assume-note-1)*:
|
||
|
||
The expression is potentially evaluated ([[basic.def.odr]](basic.def.odr "6.3 One-definition rule"))[.](#assume-2.sentence-1)
|
||
|
||
The use of assumptions is intended to allow implementations
|
||
to analyze the form of the expression and
|
||
deduce information used to optimize the program[.](#assume-2.sentence-2)
|
||
|
||
Implementations are not required to deduce
|
||
any information from any particular assumption[.](#assume-2.sentence-3)
|
||
|
||
It is expected that the value of
|
||
a [*has-attribute-expression*](cpp.cond#nt:has-attribute-expression "15.2 Conditional inclusion [cpp.cond]") for the assume attribute
|
||
is 0 if an implementation does not attempt to deduce
|
||
any such information from assumptions[.](#assume-2.sentence-4)
|
||
|
||
â *end note*]
|
||
|
||
[3](#assume-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L9697)
|
||
|
||
[*Example [1](#assume-example-1)*: int divide_by_32(int x) {[[assume(x >= 0)]]; return x/32; // The instructions produced for the division// may omit handling of negative values.}int f(int y) {[[assume(++y == 43)]]; // y is not incrementedreturn y; // statement may be replaced with return 42;} â *end example*]
|
||
|
||
### [9.13.4](#deprecated) Deprecated attribute [[dcl.attr.deprecated]](dcl.attr.deprecated)
|
||
|
||
[1](#deprecated-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L9715)
|
||
|
||
The [*attribute-token*](#nt:attribute-token "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") deprecated can be used to mark names and entities
|
||
whose use is still allowed, but is discouraged for some reason[.](#deprecated-1.sentence-1)
|
||
|
||
[*Note [1](#deprecated-note-1)*:
|
||
|
||
In particular,deprecated is appropriate for names and entities that are deemed obsolescent or
|
||
unsafe[.](#deprecated-1.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
An[*attribute-argument-clause*](#nt:attribute-argument-clause "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") may be present and, if present, it shall have the form:
|
||
|
||
( [*unevaluated-string*](lex.string.uneval#nt:unevaluated-string "5.13.6 Unevaluated strings [lex.string.uneval]") )
|
||
|
||
[*Note [2](#deprecated-note-2)*:
|
||
|
||
The [*unevaluated-string*](lex.string.uneval#nt:unevaluated-string "5.13.6 Unevaluated strings [lex.string.uneval]") in the [*attribute-argument-clause*](#nt:attribute-argument-clause "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") can be used to explain the rationale for deprecation and/or to suggest a replacing entity[.](#deprecated-1.sentence-3)
|
||
|
||
â *end note*]
|
||
|
||
[2](#deprecated-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L9733)
|
||
|
||
The attribute may be applied to the declaration of
|
||
a class,
|
||
a type alias,
|
||
a variable,
|
||
a non-static data member,
|
||
a function,
|
||
a namespace,
|
||
an enumeration,
|
||
an enumerator,
|
||
a concept, or
|
||
a template specialization[.](#deprecated-2.sentence-1)
|
||
|
||
[3](#deprecated-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L9746)
|
||
|
||
An entity declared without the deprecated attribute can later be redeclared
|
||
with the attribute and vice-versa[.](#deprecated-3.sentence-1)
|
||
|
||
[*Note [3](#deprecated-note-3)*:
|
||
|
||
Thus, an entity initially declared without the
|
||
attribute can be marked as deprecated by a subsequent redeclaration[.](#deprecated-3.sentence-2)
|
||
|
||
However, after an entity
|
||
is marked as deprecated, later redeclarations do not un-deprecate the entity[.](#deprecated-3.sentence-3)
|
||
|
||
â *end note*]
|
||
|
||
Redeclarations using different forms of the attribute (with or without the[*attribute-argument-clause*](#nt:attribute-argument-clause "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") or with different[*attribute-argument-clause*](#nt:attribute-argument-clause "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]")*s*) are allowed[.](#deprecated-3.sentence-4)
|
||
|
||
[4](#deprecated-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L9758)
|
||
|
||
*Recommended practice*: Implementations should use the deprecated attribute to produce a diagnostic
|
||
message in case the program refers to a name or entity other than to declare it, after a
|
||
declaration that specifies the attribute[.](#deprecated-4.sentence-1)
|
||
|
||
The diagnostic message should include the text provided
|
||
within the [*attribute-argument-clause*](#nt:attribute-argument-clause "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") of any deprecated attribute applied
|
||
to the name or entity[.](#deprecated-4.sentence-2)
|
||
|
||
The value of
|
||
a [*has-attribute-expression*](cpp.cond#nt:has-attribute-expression "15.2 Conditional inclusion [cpp.cond]") for the deprecated attribute
|
||
should be 0 unless the implementation can issue such diagnostic messages[.](#deprecated-4.sentence-3)
|
||
|
||
### [9.13.5](#fallthrough) Fallthrough attribute [[dcl.attr.fallthrough]](dcl.attr.fallthrough)
|
||
|
||
[1](#fallthrough-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L9773)
|
||
|
||
The [*attribute-token*](#nt:attribute-token "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") fallthrough may be applied to a [null statement](stmt.expr#def:statement,null "8.3 Expression statement [stmt.expr]"); such a statement is a fallthrough statement[.](#fallthrough-1.sentence-1)
|
||
|
||
No [*attribute-argument-clause*](#nt:attribute-argument-clause "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") shall be present[.](#fallthrough-1.sentence-2)
|
||
|
||
A fallthrough statement may only appear within
|
||
an enclosing switch statement ([[stmt.switch]](stmt.switch "8.5.3 The switch statement"))[.](#fallthrough-1.sentence-3)
|
||
|
||
The next statement that would be executed after a fallthrough statement
|
||
shall be a labeled statement whose label is a case label or
|
||
default label for the same switch statement and,
|
||
if the fallthrough statement is contained in an iteration statement,
|
||
the next statement shall be part of the same execution of
|
||
the substatement of the innermost enclosing iteration statement[.](#fallthrough-1.sentence-4)
|
||
|
||
The program is ill-formed if there is no such statement[.](#fallthrough-1.sentence-5)
|
||
|
||
[2](#fallthrough-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L9789)
|
||
|
||
*Recommended practice*: The use of a fallthrough statement should suppress
|
||
a warning that an implementation might otherwise issue
|
||
for a case or default label that is reachable
|
||
from another case or default label along some path of execution[.](#fallthrough-2.sentence-1)
|
||
|
||
The value of
|
||
a [*has-attribute-expression*](cpp.cond#nt:has-attribute-expression "15.2 Conditional inclusion [cpp.cond]") for the fallthrough attribute
|
||
should be 0 if the attribute does not cause suppression of such warnings[.](#fallthrough-2.sentence-2)
|
||
|
||
Implementations should issue a warning
|
||
if a fallthrough statement is not dynamically reachable[.](#fallthrough-2.sentence-3)
|
||
|
||
[3](#fallthrough-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L9802)
|
||
|
||
[*Example [1](#fallthrough-example-1)*: void f(int n) {void g(), h(), i(); switch (n) {case 1:case 2: g(); [[fallthrough]]; case 3: // warning on fallthrough discourageddo {[[fallthrough]]; // error: next statement is not part of the same substatement execution} while (false); case 6:do {[[fallthrough]]; // error: next statement is not part of the same substatement execution} while (n--); case 7:while (false) {[[fallthrough]]; // error: next statement is not part of the same substatement execution}case 5: h(); case 4: // implementation may warn on fallthrough i(); [[fallthrough]]; // error}} â *end example*]
|
||
|
||
### [9.13.6](#indet) Indeterminate storage [[dcl.attr.indet]](dcl.attr.indet)
|
||
|
||
[1](#indet-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L9837)
|
||
|
||
The [*attribute-token*](#nt:attribute-token "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") indeterminate may be applied
|
||
to the definition of a block variable with automatic storage duration or
|
||
to a [*parameter-declaration*](dcl.fct#nt:parameter-declaration "9.3.4.6 Functions [dcl.fct]") of a function declaration[.](#indet-1.sentence-1)
|
||
|
||
No [*attribute-argument-clause*](#nt:attribute-argument-clause "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") shall be present[.](#indet-1.sentence-2)
|
||
|
||
The attribute specifies
|
||
that the storage of an object with automatic storage duration
|
||
is initially indeterminate rather than erroneous ([[basic.indet]](basic.indet "6.8.5 Indeterminate and erroneous values"))[.](#indet-1.sentence-3)
|
||
|
||
[2](#indet-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L9846)
|
||
|
||
If a function parameter is declared with the indeterminate attribute,
|
||
it shall be so declared in the first declaration of its function[.](#indet-2.sentence-1)
|
||
|
||
If a function parameter is declared with
|
||
the indeterminate attribute in the first declaration of its function
|
||
in one translation unit and
|
||
the same function is declared without the indeterminate attribute
|
||
on the same parameter in its first declaration in another translation unit,
|
||
the program is ill-formed, no diagnostic required[.](#indet-2.sentence-2)
|
||
|
||
[3](#indet-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L9856)
|
||
|
||
[*Note [1](#indet-note-1)*:
|
||
|
||
Reading from an uninitialized variable
|
||
that is marked [[indeterminate]] can cause undefined behavior[.](#indet-3.sentence-1)
|
||
|
||
void f(int);void g() {int x [[indeterminate]], y;
|
||
f(y); // erroneous behavior ([[basic.indet]](basic.indet "6.8.5 Indeterminate and erroneous values")) f(x); // undefined behavior}struct T { T() {}int x;};int h(T t [[indeterminate]]) { f(t.x); // undefined behavior when called belowreturn 0;}int _ = h(T()); â *end note*]
|
||
|
||
### [9.13.7](#likelihood) Likelihood attributes [[dcl.attr.likelihood]](dcl.attr.likelihood)
|
||
|
||
[1](#likelihood-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L9884)
|
||
|
||
The [*attribute-token*](#nt:attribute-token "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]")*s*likely and unlikely may be applied to labels or statements[.](#likelihood-1.sentence-1)
|
||
|
||
No [*attribute-argument-clause*](#nt:attribute-argument-clause "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") shall be present[.](#likelihood-1.sentence-2)
|
||
|
||
The [*attribute-token*](#nt:attribute-token "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") likely shall not appear in an [*attribute-specifier-seq*](#nt:attribute-specifier-seq "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") that contains the [*attribute-token*](#nt:attribute-token "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") unlikely[.](#likelihood-1.sentence-3)
|
||
|
||
[2](#likelihood-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L9893)
|
||
|
||
[*Note [1](#likelihood-note-1)*:
|
||
|
||
The use of the likely attribute
|
||
is intended to allow implementations to optimize for
|
||
the case where paths of execution including it
|
||
are arbitrarily more likely
|
||
than any alternative path of execution
|
||
that does not include such an attribute on a statement or label[.](#likelihood-2.sentence-1)
|
||
|
||
The use of the unlikely attribute
|
||
is intended to allow implementations to optimize for
|
||
the case where paths of execution including it
|
||
are arbitrarily more unlikely
|
||
than any alternative path of execution
|
||
that does not include such an attribute on a statement or label[.](#likelihood-2.sentence-2)
|
||
|
||
It is expected that the value of a [*has-attribute-expression*](cpp.cond#nt:has-attribute-expression "15.2 Conditional inclusion [cpp.cond]") for the likely and unlikely attributes
|
||
is 0 if the implementation does not attempt to use these attributes
|
||
for such optimizations[.](#likelihood-2.sentence-3)
|
||
|
||
A path of execution includes a label
|
||
if and only if it contains a jump to that label[.](#likelihood-2.sentence-4)
|
||
|
||
â *end note*]
|
||
|
||
[*Note [2](#likelihood-note-2)*:
|
||
|
||
Excessive usage of either of these attributes
|
||
is liable to result in performance degradation[.](#likelihood-2.sentence-5)
|
||
|
||
â *end note*]
|
||
|
||
[3](#likelihood-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L9920)
|
||
|
||
[*Example [1](#likelihood-example-1)*: void g(int);int f(int n) {if (n > 5) [[unlikely]] { // n > 5 is considered to be arbitrarily unlikely g(0); return n * 2 + 1; }switch (n) {case 1: g(1); [[fallthrough]]; [[likely]] case 2: // n == 2 is considered to be arbitrarily more g(2); // likely than any other value of nbreak; }return 3;} â *end example*]
|
||
|
||
### [9.13.8](#unused) Maybe unused attribute [[dcl.attr.unused]](dcl.attr.unused)
|
||
|
||
[1](#unused-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L9947)
|
||
|
||
The [*attribute-token*](#nt:attribute-token "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") maybe_unused indicates that a name, label, or entity is possibly intentionally unused[.](#unused-1.sentence-1)
|
||
|
||
No [*attribute-argument-clause*](#nt:attribute-argument-clause "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") shall be present[.](#unused-1.sentence-2)
|
||
|
||
[2](#unused-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L9952)
|
||
|
||
The attribute may be applied to the declaration of a class,
|
||
type alias,
|
||
variable (including a structured binding declaration),
|
||
structured binding,
|
||
result binding ([[dcl.contract.res]](dcl.contract.res "9.4.2 Referring to the result object")),
|
||
non-static data member,
|
||
function,
|
||
enumeration, or
|
||
enumerator, or
|
||
to an [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]") label ([[stmt.label]](stmt.label "8.2 Label"))[.](#unused-2.sentence-1)
|
||
|
||
[3](#unused-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L9964)
|
||
|
||
A name or entity declared without the maybe_unused attribute
|
||
can later be redeclared with the attribute
|
||
and vice versa[.](#unused-3.sentence-1)
|
||
|
||
An entity is considered marked
|
||
after the first declaration that marks it[.](#unused-3.sentence-2)
|
||
|
||
[4](#unused-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L9971)
|
||
|
||
*Recommended practice*: For an entity marked maybe_unused,
|
||
implementations should not emit a warning
|
||
that the entity or its structured bindings (if any)
|
||
are used or unused[.](#unused-4.sentence-1)
|
||
|
||
For a structured binding declaration not marked maybe_unused,
|
||
implementations should not emit such a warning unless
|
||
all of its structured bindings are unused[.](#unused-4.sentence-2)
|
||
|
||
For a label to which maybe_unused is applied,
|
||
implementations should not emit a warning that the label is used or unused[.](#unused-4.sentence-3)
|
||
|
||
The value of
|
||
a [*has-attribute-expression*](cpp.cond#nt:has-attribute-expression "15.2 Conditional inclusion [cpp.cond]") for the maybe_unused attribute
|
||
should be 0 if the attribute does not cause suppression of such warnings[.](#unused-4.sentence-4)
|
||
|
||
[5](#unused-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L9987)
|
||
|
||
[*Example [1](#unused-example-1)*: [[maybe_unused]] void f([[maybe_unused]] bool thing1, [[maybe_unused]] bool thing2) {[[maybe_unused]] bool b = thing1 && thing2;
|
||
assert(b);#ifdef NDEBUG goto x;#endif[[maybe_unused]] x:}
|
||
|
||
Implementations should not warn that b or x is unused,
|
||
whether or not NDEBUG is defined[.](#unused-5.sentence-1)
|
||
|
||
â *end example*]
|
||
|
||
### [9.13.9](#nodiscard) Nodiscard attribute [[dcl.attr.nodiscard]](dcl.attr.nodiscard)
|
||
|
||
[1](#nodiscard-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L10007)
|
||
|
||
The [*attribute-token*](#nt:attribute-token "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") nodiscard may be applied to a function or a lambda call operator or
|
||
to the declaration of a class or enumeration[.](#nodiscard-1.sentence-1)
|
||
|
||
An [*attribute-argument-clause*](#nt:attribute-argument-clause "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") may be present
|
||
and, if present, shall have the form:
|
||
|
||
( [*unevaluated-string*](lex.string.uneval#nt:unevaluated-string "5.13.6 Unevaluated strings [lex.string.uneval]") )
|
||
|
||
[2](#nodiscard-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L10017)
|
||
|
||
A name or entity declared without the nodiscard attribute
|
||
can later be redeclared with the attribute and vice-versa[.](#nodiscard-2.sentence-1)
|
||
|
||
[*Note [1](#nodiscard-note-1)*:
|
||
|
||
Thus, an entity initially declared without the attribute
|
||
can be marked as nodiscard by a subsequent redeclaration[.](#nodiscard-2.sentence-2)
|
||
|
||
However, after an entity is marked as nodiscard,
|
||
later redeclarations do not remove the nodiscard from the entity[.](#nodiscard-2.sentence-3)
|
||
|
||
â *end note*]
|
||
|
||
Redeclarations using different forms of the attribute
|
||
(with or without the [*attribute-argument-clause*](#nt:attribute-argument-clause "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") or with different [*attribute-argument-clause*](#nt:attribute-argument-clause "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]")*s*)
|
||
are allowed[.](#nodiscard-2.sentence-4)
|
||
|
||
[3](#nodiscard-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L10033)
|
||
|
||
A [*nodiscard type*](#def:type,nodiscard "9.13.9 Nodiscard attribute [dcl.attr.nodiscard]") is
|
||
a (possibly cv-qualified) class or enumeration type
|
||
marked nodiscard in a reachable declaration[.](#nodiscard-3.sentence-1)
|
||
|
||
A [*nodiscard call*](#def:call,nodiscard "9.13.9 Nodiscard attribute [dcl.attr.nodiscard]") is either
|
||
|
||
- [(3.1)](#nodiscard-3.1)
|
||
|
||
a function call expression ([[expr.call]](expr.call "7.6.1.3 Function call"))
|
||
that calls a function declared nodiscard in a reachable declaration or
|
||
whose return type is a nodiscard type, or
|
||
|
||
- [(3.2)](#nodiscard-3.2)
|
||
|
||
an explicit type
|
||
conversion ([[expr.type.conv]](expr.type.conv "7.6.1.4 Explicit type conversion (functional notation)"), [[expr.static.cast]](expr.static.cast "7.6.1.9 Static cast"), [[expr.cast]](expr.cast "7.6.3 Explicit type conversion (cast notation)"))
|
||
that constructs an object through
|
||
a constructor declared nodiscard in a reachable declaration, or
|
||
that initializes an object of a nodiscard type[.](#nodiscard-3.sentence-2)
|
||
|
||
[4](#nodiscard-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L10051)
|
||
|
||
*Recommended practice*: Appearance of a nodiscard call as
|
||
a potentially-evaluated discarded-value expression ([[expr.prop]](expr.prop "7.2 Properties of expressions"))
|
||
of non-void type
|
||
is discouraged unless explicitly cast to void[.](#nodiscard-4.sentence-1)
|
||
|
||
Implementations should issue a warning in such cases[.](#nodiscard-4.sentence-2)
|
||
|
||
The value of
|
||
a [*has-attribute-expression*](cpp.cond#nt:has-attribute-expression "15.2 Conditional inclusion [cpp.cond]") for the nodiscard attribute
|
||
should be 0 unless the implementation can issue such warnings[.](#nodiscard-4.sentence-3)
|
||
|
||
[*Note [2](#nodiscard-note-2)*:
|
||
|
||
This is typically because discarding the return value
|
||
of a nodiscard call has surprising consequences[.](#nodiscard-4.sentence-4)
|
||
|
||
â *end note*]
|
||
|
||
The [*unevaluated-string*](lex.string.uneval#nt:unevaluated-string "5.13.6 Unevaluated strings [lex.string.uneval]") in a nodiscard [*attribute-argument-clause*](#nt:attribute-argument-clause "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") should be used in the message of the warning
|
||
as the rationale for why the result should not be discarded[.](#nodiscard-4.sentence-5)
|
||
|
||
[5](#nodiscard-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L10070)
|
||
|
||
[*Example [1](#nodiscard-example-1)*: struct [[nodiscard]] my_scopeguard { /* ... */ };struct my_unique { my_unique() = default; // does not acquire resource[[nodiscard]] my_unique(int fd) { /* ... */ } // acquires resource~my_unique() noexcept { /* ... */ } // releases resource, if any/* ... */};struct [[nodiscard]] error_info { /* ... */ };
|
||
error_info enable_missile_safety_mode();void launch_missiles();void test_missiles() { my_scopeguard(); // warning encouraged(void)my_scopeguard(), // warning not encouraged, cast to void launch_missiles(); // comma operator, statement continues my_unique(42); // warning encouraged my_unique(); // warning not encouraged enable_missile_safety_mode(); // warning encouraged launch_missiles();} error_info &foo();void f() { foo(); } // warning not encouraged: not a nodiscard call, because neither// the (reference) return type nor the function is declared nodiscard â *end example*]
|
||
|
||
### [9.13.10](#noreturn) Noreturn attribute [[dcl.attr.noreturn]](dcl.attr.noreturn)
|
||
|
||
[1](#noreturn-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L10101)
|
||
|
||
The [*attribute-token*](#nt:attribute-token "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") noreturn specifies that a function does not return[.](#noreturn-1.sentence-1)
|
||
|
||
No [*attribute-argument-clause*](#nt:attribute-argument-clause "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") shall be present[.](#noreturn-1.sentence-2)
|
||
|
||
The attribute may be applied to a function or a lambda call operator[.](#noreturn-1.sentence-3)
|
||
|
||
The first declaration of a function shall
|
||
specify the noreturn attribute if any declaration of that function specifies thenoreturn attribute[.](#noreturn-1.sentence-4)
|
||
|
||
If a function is declared with the noreturn attribute in one
|
||
translation unit and the same function is declared without the noreturn attribute in another
|
||
translation unit, the program is ill-formed, no diagnostic required[.](#noreturn-1.sentence-5)
|
||
|
||
[2](#noreturn-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L10111)
|
||
|
||
If a function f is invoked where f was previously declared with the noreturn attribute and that invocation eventually returns,
|
||
the behavior is runtime-undefined[.](#noreturn-2.sentence-1)
|
||
|
||
[*Note [1](#noreturn-note-1)*:
|
||
|
||
The function can
|
||
terminate by throwing an exception[.](#noreturn-2.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
[3](#noreturn-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L10120)
|
||
|
||
*Recommended practice*: Implementations should issue a
|
||
warning if a function marked [[noreturn]] might return[.](#noreturn-3.sentence-1)
|
||
|
||
The value of
|
||
a [*has-attribute-expression*](cpp.cond#nt:has-attribute-expression "15.2 Conditional inclusion [cpp.cond]") for the noreturn attribute
|
||
should be 0 unless the implementation can issue such warnings[.](#noreturn-3.sentence-2)
|
||
|
||
[4](#noreturn-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L10128)
|
||
|
||
[*Example [1](#noreturn-example-1)*: [[ noreturn ]] void f() {throw "error"; // OK}[[ noreturn ]] void q(int i) { // behavior is undefined if called with an argument <= 0if (i > 0)throw "positive";} â *end example*]
|
||
|
||
### [9.13.11](#nouniqueaddr) No unique address attribute [[dcl.attr.nouniqueaddr]](dcl.attr.nouniqueaddr)
|
||
|
||
[1](#nouniqueaddr-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L10145)
|
||
|
||
The [*attribute-token*](#nt:attribute-token "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") no_unique_address specifies that a non-static data member
|
||
is a potentially-overlapping subobject ([[intro.object]](intro.object "6.8.2 Object model"))[.](#nouniqueaddr-1.sentence-1)
|
||
|
||
No [*attribute-argument-clause*](#nt:attribute-argument-clause "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") shall be present[.](#nouniqueaddr-1.sentence-2)
|
||
|
||
The attribute may appertain to a non-static data member
|
||
other than a bit-field[.](#nouniqueaddr-1.sentence-3)
|
||
|
||
[2](#nouniqueaddr-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L10153)
|
||
|
||
[*Note [1](#nouniqueaddr-note-1)*:
|
||
|
||
The non-static data member can share the address of
|
||
another non-static data member or that of a base class,
|
||
and any padding that would normally be inserted
|
||
at the end of the object
|
||
can be reused as storage for other members[.](#nouniqueaddr-2.sentence-1)
|
||
|
||
â *end note*]
|
||
|
||
*Recommended practice*: The value of a [*has-attribute-expression*](cpp.cond#nt:has-attribute-expression "15.2 Conditional inclusion [cpp.cond]") for the no_unique_address attribute
|
||
should be 0 for a given implementation
|
||
unless this attribute can cause a potentially-overlapping subobject
|
||
to have zero size[.](#nouniqueaddr-2.sentence-2)
|
||
|
||
[*Example [1](#nouniqueaddr-example-1)*: template<typename Key, typename Value, typename Hash, typename Pred, typename Allocator>class hash_map {[[no_unique_address]] Hash hasher; [[no_unique_address]] Pred pred; [[no_unique_address]] Allocator alloc;
|
||
Bucket *buckets; // ...public:// ...};
|
||
|
||
Here, hasher, pred, and alloc could have the same address as buckets if their respective types are all empty[.](#nouniqueaddr-2.sentence-3)
|
||
|
||
â *end example*]
|
||
|
||
### [9.13.12](#annotation) Annotations [[dcl.attr.annotation]](dcl.attr.annotation)
|
||
|
||
[1](#annotation-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L10191)
|
||
|
||
An annotation may be applied to any declaration of a
|
||
type,
|
||
type alias,
|
||
variable,
|
||
function,
|
||
namespace,
|
||
enumerator,[*base-specifier*](class.derived.general#nt:base-specifier "11.7.1 General [class.derived.general]"), or
|
||
non-static data member[.](#annotation-1.sentence-1)
|
||
|
||
[2](#annotation-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L10202)
|
||
|
||
Let E be the expressionstd::meta::reflect_constant([*constant-expression*](expr.const#nt:constant-expression "7.7 Constant expressions [expr.const]"))[.](#annotation-2.sentence-1)
|
||
|
||
E shall be a constant expression;
|
||
the result of E is the [*underlying constant*](#def:constant,underlying "9.13.12 Annotations [dcl.attr.annotation]") of the annotation[.](#annotation-2.sentence-2)
|
||
|
||
[3](#annotation-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L10208)
|
||
|
||
Each [*annotation*](#nt:annotation "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") produces a unique annotation[.](#annotation-3.sentence-1)
|
||
|
||
[4](#annotation-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L10211)
|
||
|
||
Substituting into an [*annotation*](#nt:annotation "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") is not in the immediate context[.](#annotation-4.sentence-1)
|
||
|
||
[*Example [1](#annotation-example-1)*:
|
||
|
||
[[=1]] void f();[[=2, =3, =2]] void g();void g [[=4, =2]] ();f has one annotation
|
||
and g has five annotations[.](#annotation-4.sentence-2)
|
||
|
||
These can be queried with metafunctions
|
||
such as std::meta::annotations_of ([[meta.reflection.annotation]](meta.reflection.annotation "21.4.18 Annotation reflection"))[.](#annotation-4.sentence-3)
|
||
|
||
â *end example*]
|
||
|
||
[*Example [2](#annotation-example-2)*: template<class T>[[=T::type()]] void f(T t);
|
||
|
||
void f(int);
|
||
|
||
void g() { f(0); // OK f('0'); // error, substituting into the annotation results in an invalid expression} â *end example*]
|