Files
2025-10-25 03:02:53 +03:00

882 lines
52 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

[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.1Attribute syntax and semantics[dcl.attr.grammar]")
[*attribute-specifier*](#nt:attribute-specifier "9.13.1Attribute syntax and semantics[dcl.attr.grammar]") [*attribute-specifier-seq*](#nt:attribute-specifier-seq "9.13.1Attribute syntax and semantics[dcl.attr.grammar]")opt
[attribute-specifier:](#nt:attribute-specifier "9.13.1Attribute syntax and semantics[dcl.attr.grammar]")
[ [ [*attribute-using-prefix*](#nt:attribute-using-prefix "9.13.1Attribute syntax and semantics[dcl.attr.grammar]")opt [*attribute-list*](#nt:attribute-list "9.13.1Attribute syntax and semantics[dcl.attr.grammar]") ] ]
[ [ [*annotation-list*](#nt:annotation-list "9.13.1Attribute syntax and semantics[dcl.attr.grammar]") ] ]
[*alignment-specifier*](#nt:alignment-specifier "9.13.1Attribute syntax and semantics[dcl.attr.grammar]")
[alignment-specifier:](#nt:alignment-specifier "9.13.1Attribute syntax and semantics[dcl.attr.grammar]")
alignas ( [*type-id*](dcl.name#nt:type-id "9.3.2Type names[dcl.name]") ...opt )
alignas ( [*constant-expression*](expr.const#nt:constant-expression "7.7Constant expressions[expr.const]") ...opt )
[attribute-using-prefix:](#nt:attribute-using-prefix "9.13.1Attribute syntax and semantics[dcl.attr.grammar]")
using [*attribute-namespace*](#nt:attribute-namespace "9.13.1Attribute syntax and semantics[dcl.attr.grammar]") :
[attribute-list:](#nt:attribute-list "9.13.1Attribute syntax and semantics[dcl.attr.grammar]")
[*attribute*](#nt:attribute "9.13.1Attribute syntax and semantics[dcl.attr.grammar]")opt
[*attribute-list*](#nt:attribute-list "9.13.1Attribute syntax and semantics[dcl.attr.grammar]") , [*attribute*](#nt:attribute "9.13.1Attribute syntax and semantics[dcl.attr.grammar]")opt
[*attribute*](#nt:attribute "9.13.1Attribute syntax and semantics[dcl.attr.grammar]") ...
[*attribute-list*](#nt:attribute-list "9.13.1Attribute syntax and semantics[dcl.attr.grammar]") , [*attribute*](#nt:attribute "9.13.1Attribute syntax and semantics[dcl.attr.grammar]") ...
[annotation-list:](#nt:annotation-list "9.13.1Attribute syntax and semantics[dcl.attr.grammar]")
[*annotation*](#nt:annotation "9.13.1Attribute syntax and semantics[dcl.attr.grammar]") ...opt
[*annotation-list*](#nt:annotation-list "9.13.1Attribute syntax and semantics[dcl.attr.grammar]") , [*annotation*](#nt:annotation "9.13.1Attribute syntax and semantics[dcl.attr.grammar]") ...opt
[attribute:](#nt:attribute "9.13.1Attribute syntax and semantics[dcl.attr.grammar]")
[*attribute-token*](#nt:attribute-token "9.13.1Attribute syntax and semantics[dcl.attr.grammar]") [*attribute-argument-clause*](#nt:attribute-argument-clause "9.13.1Attribute syntax and semantics[dcl.attr.grammar]")opt
[annotation:](#nt:annotation "9.13.1Attribute syntax and semantics[dcl.attr.grammar]")
= [*constant-expression*](expr.const#nt:constant-expression "7.7Constant expressions[expr.const]")
[attribute-token:](#nt:attribute-token "9.13.1Attribute syntax and semantics[dcl.attr.grammar]")
[*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]")
[*attribute-scoped-token*](#nt:attribute-scoped-token "9.13.1Attribute syntax and semantics[dcl.attr.grammar]")
[attribute-scoped-token:](#nt:attribute-scoped-token "9.13.1Attribute syntax and semantics[dcl.attr.grammar]")
[*attribute-namespace*](#nt:attribute-namespace "9.13.1Attribute syntax and semantics[dcl.attr.grammar]") :: [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]")
[attribute-namespace:](#nt:attribute-namespace "9.13.1Attribute syntax and semantics[dcl.attr.grammar]")
[*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]")
[attribute-argument-clause:](#nt:attribute-argument-clause "9.13.1Attribute syntax and semantics[dcl.attr.grammar]")
( [*balanced-token-seq*](#nt:balanced-token-seq "9.13.1Attribute syntax and semantics[dcl.attr.grammar]")opt )
[balanced-token-seq:](#nt:balanced-token-seq "9.13.1Attribute syntax and semantics[dcl.attr.grammar]")
[*balanced-token*](#nt:balanced-token "9.13.1Attribute syntax and semantics[dcl.attr.grammar]") [*balanced-token-seq*](#nt:balanced-token-seq "9.13.1Attribute syntax and semantics[dcl.attr.grammar]")opt
[balanced-token:](#nt:balanced-token "9.13.1Attribute syntax and semantics[dcl.attr.grammar]")
( [*balanced-token-seq*](#nt:balanced-token-seq "9.13.1Attribute syntax and semantics[dcl.attr.grammar]")opt )
[ [*balanced-token-seq*](#nt:balanced-token-seq "9.13.1Attribute syntax and semantics[dcl.attr.grammar]")opt ]
{ [*balanced-token-seq*](#nt:balanced-token-seq "9.13.1Attribute syntax and semantics[dcl.attr.grammar]")opt }
[: [*balanced-token-seq*](#nt:balanced-token-seq "9.13.1Attribute syntax and semantics[dcl.attr.grammar]")opt :]
any [*token*](lex.token#nt:token "5.10Tokens[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.1Attribute syntax and semantics[dcl.attr.grammar]") contains an [*attribute-using-prefix*](#nt:attribute-using-prefix "9.13.1Attribute syntax and semantics[dcl.attr.grammar]"),
the [*attribute-list*](#nt:attribute-list "9.13.1Attribute syntax and semantics[dcl.attr.grammar]") following that [*attribute-using-prefix*](#nt:attribute-using-prefix "9.13.1Attribute syntax and semantics[dcl.attr.grammar]") shall not contain an [*attribute-scoped-token*](#nt:attribute-scoped-token "9.13.1Attribute syntax and semantics[dcl.attr.grammar]") and every [*attribute-token*](#nt:attribute-token "9.13.1Attribute syntax and semantics[dcl.attr.grammar]") in that [*attribute-list*](#nt:attribute-list "9.13.1Attribute syntax and semantics[dcl.attr.grammar]") is treated as if
its [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]") were prefixed with N::,
where N is the [*attribute-namespace*](#nt:attribute-namespace "9.13.1Attribute syntax and semantics[dcl.attr.grammar]") specified in the [*attribute-using-prefix*](#nt:attribute-using-prefix "9.13.1Attribute 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.1Attribute syntax and semantics[dcl.attr.grammar]") affects the tokens in an [*attribute-argument-clause*](#nt:attribute-argument-clause "9.13.1Attribute 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.1Attribute 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.1Attribute syntax and semantics[dcl.attr.grammar]"), an ellipsis may appear only if that[*attribute*](#nt:attribute "9.13.1Attribute syntax and semantics[dcl.attr.grammar]")'s specification permits it[.](#grammar-4.sentence-1)
An [*attribute*](#nt:attribute "9.13.1Attribute syntax and semantics[dcl.attr.grammar]") followed
by an ellipsis is a [pack expansion](temp.variadic#def:pack_expansion "13.7.4Variadic templates[temp.variadic]")[.](#grammar-4.sentence-2)
An [*attribute-specifier*](#nt:attribute-specifier "9.13.1Attribute syntax and semantics[dcl.attr.grammar]") that contains
an [*attribute-list*](#nt:attribute-list "9.13.1Attribute syntax and semantics[dcl.attr.grammar]") with no [*attribute*](#nt:attribute "9.13.1Attribute syntax and semantics[dcl.attr.grammar]")*s* and no [*alignment-specifier*](#nt:alignment-specifier "9.13.1Attribute 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.1Attribute syntax and semantics[dcl.attr.grammar]")*s* appear in an[*attribute-list*](#nt:attribute-list "9.13.1Attribute syntax and semantics[dcl.attr.grammar]") is not significant[.](#grammar-4.sentence-4)
If a[keyword](lex.key "5.12Keywords[lex.key]") or an [alternative token](lex.digraph "5.9Alternative tokens[lex.digraph]") that satisfies the syntactic requirements
of an [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]") ([[lex.name]](lex.name "5.11Identifiers")) is
contained in
an [*attribute-token*](#nt:attribute-token "9.13.1Attribute syntax and semantics[dcl.attr.grammar]"), it is considered an identifier[.](#grammar-4.sentence-5)
No[name lookup](basic.lookup "6.5Name lookup[basic.lookup]") is performed on any of the identifiers contained in an[*attribute-token*](#nt:attribute-token "9.13.1Attribute syntax and semantics[dcl.attr.grammar]")[.](#grammar-4.sentence-6)
The [*attribute-token*](#nt:attribute-token "9.13.1Attribute syntax and semantics[dcl.attr.grammar]") determines additional
requirements on the [*attribute-argument-clause*](#nt:attribute-argument-clause "9.13.1Attribute 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.1Attribute syntax and semantics[dcl.attr.grammar]") followed by an ellipsis
is a pack expansion ([[temp.variadic]](temp.variadic "13.7.4Variadic 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.1Attribute syntax and semantics[dcl.attr.grammar]") is said to [*appertain*](#def:appertain "9.13.1Attribute syntax and semantics[dcl.attr.grammar]") to some entity or
statement, identified by the syntactic context
where it appears ([[stmt]](stmt "8Statements"), [[dcl]](dcl "9Declarations"), [[dcl.decl]](dcl.decl "9.3Declarators"))[.](#grammar-6.sentence-1)
If an [*attribute-specifier-seq*](#nt:attribute-specifier-seq "9.13.1Attribute syntax and semantics[dcl.attr.grammar]") that appertains to some
entity or statement contains an [*attribute*](#nt:attribute "9.13.1Attribute syntax and semantics[dcl.attr.grammar]") or [*alignment-specifier*](#nt:alignment-specifier "9.13.1Attribute 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.1Attribute syntax and semantics[dcl.attr.grammar]") appertains to a friend declaration ([[class.friend]](class.friend "11.8.4Friends")), 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.1Attribute syntax and semantics[dcl.attr.grammar]") cannot appertain to
an explicit instantiation ([[temp.explicit]](temp.explicit "13.9.3Explicit 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.1Attribute syntax and semantics[dcl.attr.grammar]") (including an [*attribute-scoped-token*](#nt:attribute-scoped-token "9.13.1Attribute 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.1Attribute 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.1Attribute 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.1Attribute 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.1Attribute 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.1Attribute syntax and semantics[dcl.attr.grammar]")*s* results in a program whose set of possible executions ([[intro.abstract]](intro.abstract "4.1.2Abstract 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.1Attribute syntax and semantics[dcl.attr.grammar]")[.](#grammar-7.sentence-3)
— *end note*]
An [*attribute-token*](#nt:attribute-token "9.13.1Attribute 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.1Attribute 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.1Attribute syntax and semantics[dcl.attr.grammar]") and
its [*attribute-namespace*](#nt:attribute-namespace "9.13.1Attribute 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.1Attribute syntax and semantics[dcl.attr.grammar]") in an [*attribute-scoped-token*](#nt:attribute-scoped-token "9.13.1Attribute 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.1Attribute syntax and semantics[dcl.attr.grammar]") or
within the [*balanced-token-seq*](#nt:balanced-token-seq "9.13.1Attribute syntax and semantics[dcl.attr.grammar]") of
an [*attribute-argument-clause*](#nt:attribute-argument-clause "9.13.1Attribute 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.1Attribute 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.1General[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.1Attribute 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.1Preamble[except.pre]") ([[except.handle]](except.handle "14.4Handling an exception"))[.](#dcl.align-1.sentence-1)
An [*alignment-specifier*](#nt:alignment-specifier "9.13.1Attribute 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.5Elaborated type specifiers[dcl.type.elab]") ([[dcl.type.elab]](dcl.type.elab "9.2.9.5Elaborated type specifiers")) or[*class-head*](class.pre#nt:class-head "11.1Preamble[class.pre]") ([[class]](class "11Classes")), respectively)[.](#dcl.align-1.sentence-2)
An [*alignment-specifier*](#nt:alignment-specifier "9.13.1Attribute syntax and semantics[dcl.attr.grammar]") with an ellipsis is a pack expansion ([[temp.variadic]](temp.variadic "13.7.4Variadic 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.1Attribute syntax and semantics[dcl.attr.grammar]") is of the formalignas( [*constant-expression*](expr.const#nt:constant-expression "7.7Constant expressions[expr.const]") ):
- [(2.1)](#dcl.align-2.1)
the [*constant-expression*](expr.const#nt:constant-expression "7.7Constant 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.3Alignment")), 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.1Attribute syntax and semantics[dcl.attr.grammar]") of the formalignas( [*type-id*](dcl.name#nt:type-id "9.3.2Type names[dcl.name]") ) has the same
effect as alignas([alignof](expr.alignof "7.6.2.6Alignof[expr.alignof]")( [*type-id*](dcl.name#nt:type-id "9.3.2Type 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.1Attribute syntax and semantics[dcl.attr.grammar]")*s*, if any;
otherwise, the [*alignment-specifier*](#nt:alignment-specifier "9.13.1Attribute 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.1Attribute 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.1Attribute 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.1Attribute 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.1Attribute 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.1Attribute 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.1Attribute 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.1Attribute syntax and semantics[dcl.attr.grammar]") assume may be applied to a null statement;
such a statement is an [*assumption*](#def:assumption "9.13.3Assumption attribute[dcl.attr.assume]")[.](#assume-1.sentence-1)
An [*attribute-argument-clause*](#nt:attribute-argument-clause "9.13.1Attribute syntax and semantics[dcl.attr.grammar]") shall be present and
shall have the form:
( [*conditional-expression*](expr.cond#nt:conditional-expression "7.6.16Conditional operator[expr.cond]") )
The expression is contextually converted to bool ([[conv.general]](conv.general "7.3.1General"))[.](#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.3One-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.2Conditional 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.1Attribute 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.1Attribute 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.6Unevaluated strings[lex.string.uneval]") )
[*Note [2](#deprecated-note-2)*:
The [*unevaluated-string*](lex.string.uneval#nt:unevaluated-string "5.13.6Unevaluated strings[lex.string.uneval]") in the [*attribute-argument-clause*](#nt:attribute-argument-clause "9.13.1Attribute 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.1Attribute syntax and semantics[dcl.attr.grammar]") or with different[*attribute-argument-clause*](#nt:attribute-argument-clause "9.13.1Attribute 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.1Attribute 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.2Conditional 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.1Attribute syntax and semantics[dcl.attr.grammar]") fallthrough may be applied to a [null statement](stmt.expr#def:statement,null "8.3Expression statement[stmt.expr]"); such a statement is a fallthrough statement[.](#fallthrough-1.sentence-1)
No [*attribute-argument-clause*](#nt:attribute-argument-clause "9.13.1Attribute 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.3The 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.2Conditional 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.1Attribute 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.6Functions[dcl.fct]") of a function declaration[.](#indet-1.sentence-1)
No [*attribute-argument-clause*](#nt:attribute-argument-clause "9.13.1Attribute 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.5Indeterminate 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.5Indeterminate 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.1Attribute 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.1Attribute syntax and semantics[dcl.attr.grammar]") shall be present[.](#likelihood-1.sentence-2)
The [*attribute-token*](#nt:attribute-token "9.13.1Attribute syntax and semantics[dcl.attr.grammar]") likely shall not appear in an [*attribute-specifier-seq*](#nt:attribute-specifier-seq "9.13.1Attribute syntax and semantics[dcl.attr.grammar]") that contains the [*attribute-token*](#nt:attribute-token "9.13.1Attribute 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.2Conditional 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.1Attribute 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.1Attribute 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.2Referring to the result object")),
non-static data member,
function,
enumeration, or
enumerator, or
to an [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]") label ([[stmt.label]](stmt.label "8.2Label"))[.](#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.2Conditional 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.1Attribute 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.1Attribute 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.6Unevaluated 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.1Attribute syntax and semantics[dcl.attr.grammar]") or with different [*attribute-argument-clause*](#nt:attribute-argument-clause "9.13.1Attribute 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.9Nodiscard 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.9Nodiscard attribute[dcl.attr.nodiscard]") is either
- [(3.1)](#nodiscard-3.1)
a function call expression ([[expr.call]](expr.call "7.6.1.3Function 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.4Explicit type conversion (functional notation)"), [[expr.static.cast]](expr.static.cast "7.6.1.9Static cast"), [[expr.cast]](expr.cast "7.6.3Explicit 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.2Properties 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.2Conditional 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.6Unevaluated strings[lex.string.uneval]") in a nodiscard [*attribute-argument-clause*](#nt:attribute-argument-clause "9.13.1Attribute 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.1Attribute 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.1Attribute 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.2Conditional 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.1Attribute 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.2Object model"))[.](#nouniqueaddr-1.sentence-1)
No [*attribute-argument-clause*](#nt:attribute-argument-clause "9.13.1Attribute 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.2Conditional 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.1General[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.7Constant 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.12Annotations[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.1Attribute 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.1Attribute 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.18Annotation 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*]