Последовательность спецификаторов атрибутов(начиная с 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).
Пояснение
Атрибуты предоставляют унифицированный стандартный синтаксис для расширений языка, определяемых реализацией, например расширений языка 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 из предыдущей является намеренным и не должен вызывать предупреждение компилятора, предупреждающего о таком переходе (спецификатор атрибута) |
|
{{{notes}}} | предписывает компилятору выдать предупреждение, если возвращаемое значение игнорируется (спецификатор атрибута) |
[[maybe_unused]](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