Namespaces
Variants

Attribute specifier sequence (since C23)

From cppreference.net

Вводит определяемые реализацией атрибуты для типов, объектов, выражений и т.д.

Содержание

Синтаксис

[[ attr  ]] [[ attr1 , attr2 , attr3 ( args ) ]] [[ attribute-prefix :: attr  ( args ) ]]
**Примечание:** Весь текст в данном HTML-фрагменте состоит исключительно из C++ специфичных терминов (атрибуты, аргументы, префиксы) и HTML-тегов, которые согласно инструкциям не подлежат переводу. Поэтому перевод не требуется и исходный формат полностью сохранен.

Формально синтаксис выглядит следующим образом:

[[ список-атрибутов ]] (начиная с C23)

где attribute-list представляет собой разделённый запятыми список из нуля или более attribute-token ов

стандартный-атрибут (1)
префикс-атрибута :: идентификатор (2)
стандартный-атрибут ( список-аргументов  (опционально) ) (3)
префикс-атрибута :: идентификатор ( список-аргументов  (опционально) ) (4)

где attribute-prefix является идентификатором , а argument-list представляет собой последовательность токенов, в которой круглые, квадратные и фигурные скобки сбалансированы ( balanced-token-sequence ).

1) стандартный атрибут, такой как [ [ fallthrough ] ]
2) атрибут с пространством имён, например [ [ gnu :: unused ] ]
3) стандартный атрибут с аргументами, например [ [ deprecated ( "reason" ) ] ]
4) атрибут с пространством имён и списком аргументов, например [ [ gnu :: nonnull ( 1 ) ] ]

Объяснение

Атрибуты предоставляют унифицированный стандартный синтаксис для реализационно-определенных расширений языка, таких как расширения GNU и IBM __attribute__((...)) , расширение Microsoft __declspec() , и т.д.

Атрибут может использоваться практически везде в программе на C++ и может применяться практически ко всему: к типам, переменным, функциям, именам, блокам кода, целым единицам трансляции, хотя каждый конкретный атрибут действителен только там, где это разрешено реализацией: [[expect_true]] может быть атрибутом, который можно использовать только с if , но не с объявлением класса. [[omp::parallel()]] может быть атрибутом, который применяется к блоку кода или к for циклу, но не к типу int , и т.д. (обратите внимание, что эти два атрибута являются вымышленными примерами, см. ниже стандартные и некоторые нестандартные атрибуты)

В объявлениях атрибуты могут появляться как перед всем объявлением, так и непосредственно после имени объявляемой сущности, в этом случае они комбинируются. В большинстве других ситуаций атрибуты применяются к непосредственно предшествующей сущности.

Два последовательных токена левой квадратной скобки ( [[ ) могут появляться только при введении спецификатора атрибута или внутри аргумента атрибута.

Помимо стандартных атрибутов, перечисленных ниже, реализации могут поддерживать произвольные нестандартные атрибуты с поведением, определяемым реализацией. Все неизвестные реализации атрибуты игнорируются без вызова ошибки.

Каждый стандартный-атрибут зарезервирован для стандартизации. То есть, каждый нестандартный атрибут имеет префикс префикс-атрибута , предоставляемый реализацией, например [[gnu::may_alias]] и [[clang::no_sanitize]] .

Стандартные атрибуты

Только следующие атрибуты определены стандартом C. Каждый стандартный атрибут, имя которого имеет форму attr , также может быть записан как __attr__ , и его значение не изменяется.

[[ deprecated ]] (C23) [[ deprecated (" reason ")]] (C23)
указывает, что использование имени или сущности, объявленной с этим атрибутом, разрешено, но не рекомендуется по некоторой причине
(спецификатор атрибута)
(C23)
указывает, что переход к следующей метке case является преднамеренным и не должен диагностироваться компилятором, который предупреждает о сквозном выполнении
(спецификатор атрибута)
[[ nodiscard ]] (C23) [[ nodiscard (" reason ")]] (C23)
побуждает компилятор выдавать предупреждение, если возвращаемое значение игнорируется
(спецификатор атрибута)
(C23)
подавляет предупреждения компилятора о неиспользуемых сущностях, если таковые имеются
(спецификатор атрибута)
[[ noreturn ]] (C23) [[ _Noreturn ]] (C23) (deprecated)
указывает, что функция не возвращает управление
(спецификатор атрибута)
(C23)
указывает, что функция является статической, без побочных эффектов, идемпотентной и независимой
(спецификатор атрибута)
(C23)
указывает, что функция является без побочных эффектов и идемпотентной
(спецификатор атрибута)

Тестирование атрибутов

__has_c_attribute( атрибут-токен )

Проверяет наличие токена атрибута с именем, указанным в attribute-token .

Для стандартных атрибутов он будет раскрываться в год и месяц, когда атрибут был добавлен в рабочий проект (см. таблицу ниже), наличие вендор-специфичных атрибутов определяется ненулевой целочисленной константой.

__has_c_attribute может быть раскрыто в выражениях #if и #elif . Оно рассматривается как определенный макрос #ifdef , #ifndef и defined , но не может быть использовано где-либо еще.

attribute-token Атрибут Значение Стандарт
deprecated [[ deprecated ]] 201904L (C23)
fallthrough [[ fallthrough ]] 201904L (C23)
maybe_unused [[ maybe_unused ]] 201904L (C23)
nodiscard [[ nodiscard ]] 202003L (C23)
noreturn
_Noreturn
[[ noreturn ]]
[[ _Noreturn ]]
202202L (C23)
unsequenced [[ unsequenced ]] 202207L (C23)
reproducible [[ reproducible ]] 202207L (C23)

Пример

[[gnu::hot]] [[gnu::const]] [[nodiscard]]
int f(void); // объявление f с тремя атрибутами
[[gnu::const, gnu::hot, nodiscard]]
int f(void); // то же самое, но использует один спецификатор
             // атрибутов, содержащий три атрибута
int f(void) { return 0; }
int main(void)
{
}

Ссылки

  • Стандарт C23 (ISO/IEC 9899:2024):
  • 6.7.12 Атрибуты (стр.: TBD)

Смотрите также

Документация C++ для Последовательности спецификаторов атрибутов

Внешние ссылки

1. Атрибуты в GCC
2. Атрибуты в Clang