Spec-Zone.ru › C

Последовательность спецификаторов атрибутов(начиная с C23)

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

Синтаксис

[[attr ]] [[attr1, attr2, attr3(args)]] [[attribute-prefix::attr (args)]]

Формально синтаксис имеет следующий вид:

[[ attribute-list ]] (начиная с C23)

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

standard-attribute (1)
attribute-prefix :: identifier (2)
standard-attribute ( argument-list (необязательно) ) (3)
attribute-prefix :: identifier ( argument-list (необязательно) ) (4)

где attribute-prefix — это identifier, а 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 и т. д. (обратите внимание, что эти два атрибута — вымышленные примеры; стандартные и некоторые нестандартные атрибуты приведены ниже)

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

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

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

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

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

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

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

Проверка атрибутов

__has_c_attribute( attribute-token )

Проверяет наличие токена атрибута с именем, заданным в 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); // declare f with three attributes

[[gnu::const, gnu::hot, nodiscard]]
int f(void); // the same as above, but uses a single attr
             // specifier that contains three attributes

int f(void) { return 0; }

int main(void)
{
}

Ссылки

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

См. также

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

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

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

© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/c/language/attributes

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API