10 Declarations [dcl.dcl]

10.6 Attributes [dcl.attr]

10.6.1 Attribute syntax and semantics [dcl.attr.grammar]

Атрибуты определяют дополнительную информацию для различных исходных конструкций, таких как типы, переменные, имена, блоки или единицы перевода.

attribute-specifier-seq:
	attribute-specifier-seqopt attribute-specifier
attribute-specifier:
	[ [ attribute-using-prefixopt attribute-list ] ]
	alignment-specifier
alignment-specifier:
	alignas ( type-id ...opt )
	alignas ( constant-expression ...opt )
attribute-using-prefix:
	using attribute-namespace :
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-seqopt )
balanced-token-seq:
	balanced-token
	balanced-token-seq balanced-token
balanced-token:
	( balanced-token-seqopt )
	[ balanced-token-seqopt ]
	{ balanced-token-seqopt }
	any token other than a parenthesis, a bracket, or a brace

Если an attribute-specifier содержит attribute-using-prefix, attribute-listследующее, которое attribute-using-prefix не должно содержать, attribute-scoped-token и каждый attribute-tokenв, который attribute-list обрабатывается так, как если бы его identifierпрефикс былN​::​, гдеN - это attribute-namespace указанное в attribute-using-prefix. [ Note: Это правило не накладывает ограничений на то, как объект attribute-using-prefix влияет на токены в attribute-argument-clause. ] [end noteExample:

[[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 token
  void h() {}

end example]

[ Note: Для каждого отдельного атрибута balanced-token-seqбудет указана форма . ]end note

В attribute-listобъекте многоточие может отображаться только в том случае, если это attributeразрешено спецификацией. attributeС последующим многоточием являетсяpack expansion. Не , attribute-specifierчто не содержит attributes не имеет никакого эффекта. Порядок, в котором attribute-tokens появляются символы attribute-list, не имеет значения. Если a keyword или an,alternative token которое удовлетворяет синтаксическим требованиям identifier, содержится в an attribute-token, это считается идентификатором. Нет name lookup не выполняется ни с одним из идентификаторов, содержащихся в файле attribute-token. attribute-tokenОпределяет дополнительные требования к attribute-argument-clause(если таковые имеются).

Каждый из них attribute-specifier-seqотноситсяappertain к некоторому объекту или утверждению, идентифицированному синтаксическим контекстом, в котором он встречается (пункт[stmt.stmt], пункт[dcl.dcl], пункт[dcl.decl]). Если attribute-specifier-seqэлемент, принадлежащий какой-либо сущности или оператору, содержит элемент attributeили, alignment-specifierкоторый не может применяться к этой сущности или оператору, программа сформирована неправильно. Если a attribute-specifier-seq принадлежит afriend declaration, это объявление должно быть определением. Нет attribute-specifier-seqне относится к explicit instantiation.

Для attribute-token (включая attribute-scoped-token), не указанного в этом международном стандарте, поведение определяется реализацией. Все, attribute-tokenчто не распознается реализацией, игнорируется. [ Note: Каждая реализация должна выбрать отличительное имя для attribute-namespaceфайла attribute-scoped-token. ]end note

Два последовательные левые квадратные маркеры скобки должны появляться только тогда , когда внедрив attribute-specifierили в пределах balanced-token-seqот attribute-argument-clause. [ Note: Если две последовательные левые квадратные скобки появляются там, где attribute-specifierнедопустимо, программа имеет неправильный формат, даже если скобки соответствуют альтернативной грамматической постановке. ] [end noteExample:

int p[10];
void f() {
  int x = 42, y[5];
  int(p[[x] { return x; }()]);  // error: invalid 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.
  int i [[vendor::attr([[]])]]; // well-formed implementation-defined attribute.
}

end example]