Attributes specify additional information for various source constructs such as types, variables, names, blocks, or translation units.
attribute-specifier-seq: attribute-specifier-seqopt attribute-specifier
attribute-specifier: [ [ attribute-list ] ] alignment-specifier
alignment-specifier: alignas ( type-id ...opt ) alignas ( alignment-expression ...opt )
attribute-list: attributeopt attribute-list , attributeopt attribute ... attribute-list , attribute ...
attribute: attribute-token attribute-argument-clauseopt
attribute-token: identifier attribute-scoped-token
attribute-scoped-token: attribute-namespace :: identifier
attribute-namespace: identifier
attribute-argument-clause: ( balanced-token-seq )
balanced-token-seq: balanced-tokenopt balanced-token-seq balanced-token
balanced-token: ( balanced-token-seq ) [ balanced-token-seq ] { balanced-token-seq } any token other than a parenthesis, a bracket, or a brace
[ Note: For each individual attribute, the form of the balanced-token-seq will be specified. — end note ]
In an attribute-list, an ellipsis may appear only if that attribute's specification permits it. An attribute followed by an ellipsis is a pack expansion ([temp.variadic]). An attribute-specifier that contains no attributes has no effect. The order in which the attribute-tokens appear in an attribute-list is not significant. If a keyword ([lex.key]) or an alternative token ([lex.digraph]) that satisfies the syntactic requirements of an identifier ([lex.name]) is contained in an attribute-token, it is considered an identifier. No name lookup ([basic.lookup]) is performed on any of the identifiers contained in an attribute-token. The attribute-token determines additional requirements on the attribute-argument-clause (if any). The use of an attribute-scoped-token is conditionally-supported, with implementation-defined behavior. [ Note: Each implementation should choose a distinctive name for the attribute-namespace in an attribute-scoped-token. — end note ]
Each attribute-specifier-seq is said to appertain to some entity or statement, identified by the syntactic context where it appears (Clause [stmt.stmt], Clause [dcl.dcl], Clause [dcl.decl]). If an attribute-specifier-seq that appertains to some entity or statement contains an attribute that is not allowed to apply to that entity or statement, the program is ill-formed. If an attribute-specifier-seq appertains to a friend declaration ([class.friend]), that declaration shall be a definition. No attribute-specifier-seq shall appertain to an explicit instantiation ([temp.explicit]).
For an attribute-token not specified in this International Standard, the behavior is implementation-defined.
Two consecutive left square bracket tokens shall appear only when introducing an attribute-specifier. [ Note: If two consecutive left square brackets appear where an attribute-specifier is not allowed, the program is ill formed even if the brackets match an alternative grammar production. — end note ] [ Example:
int p[10]; void f() { int x = 42, y[5]; int(p[[x] { return x; }()]); // error: malformed attribute on a nested // declarator-id 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. }
— end example ]