Spec-Zone.ru › C

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

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

Синтаксис

[[атрибут ]] [[атрибут1, атрибут2, атрибут3(аргументы)]] [[префикс-атрибута::атрибут (аргументы)]]

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

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

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

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

где префикс-атрибута — это идентификатор, а список-аргументов — это последовательность токенов, где скобки, квадратные скобки и фигурные скобки сбалансированы (сбалансированная-последовательность-токенов).

1) стандартный атрибут, такой как [[fallthrough]]
2) атрибут с именным пространством, такой как [[gnu::unused]]
3) стандартный атрибут с аргументами, такой как [[deprecated("причина")]]
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)
указывает, что использование имени или сущности, объявленной с этим атрибутом, разрешено, но не рекомендуется по некоторым причинам
(спецификатор атрибута)
[[fallthrough]](C23) указывает, что переход по метке предыдущего case-блока является преднамеренным и не должен диагностироваться компилятором, который предупреждает о переходе по метке
(спецификатор атрибута)
[[nodiscard]](C23)
[[nodiscard("reason")]](C23)
рекомендует компилятору выдать предупреждение, если значение возврата отбрасывается
(спецификатор атрибута)
[[maybe_unused]](C23) подавляет предупреждения компилятора о неиспользуемых сущностях, если таковые имеются
(спецификатор атрибута)
[[noreturn]](C23)
[[_Noreturn]](C23)(устаревшее)
указывает, что функция не возвращает значение
(спецификатор атрибута)
[[unsequenced]](C23) указывает, что функция бессостоятельна, не имеет эффектов, идемпотентна и независима
(спецификатор атрибута)
[[reproducible]](C23) указывает, что функция не имеет эффектов и идемпотентна
(спецификатор атрибута)

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

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

Проверяет наличие токена атрибута, имя которого задано токен-атрибута.

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

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

токен-атрибута Атрибут Значение Стандарт
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:2023):
    • 6.7.12 Атрибуты (стр.: TBD)

См. также

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

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

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

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

Spec-Zone.ru

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