Attribute specifier sequence (since C23)
Вводит определяемые реализацией атрибуты для типов, объектов, выражений и т.д.
Содержание |
Синтаксис
-
[[attr ]][[attr1 , attr2 , attr3(args)]][[attribute-prefix::attr (args)]]
Формально синтаксис выглядит следующим образом:
[[
список-атрибутов
]]
|
(начиная с C23) | ||||||||
где attribute-list представляет собой разделённый запятыми список из нуля или более attribute-token ов
| стандартный-атрибут | (1) | ||||||||
префикс-атрибута
::
идентификатор
|
(2) | ||||||||
стандартный-атрибут
(
список-аргументов
(опционально)
)
|
(3) | ||||||||
префикс-атрибута
::
идентификатор
(
список-аргументов
(опционально)
)
|
(4) | ||||||||
где attribute-prefix является идентификатором , а argument-list представляет собой последовательность токенов, в которой круглые, квадратные и фигурные скобки сбалансированы ( balanced-token-sequence ).
Объяснение
Атрибуты предоставляют унифицированный стандартный синтаксис для реализационно-определенных расширений языка, таких как расширения 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 является преднамеренным и не должен диагностироваться компилятором, который предупреждает о сквозном выполнении
(спецификатор атрибута) |
|
побуждает компилятор выдавать предупреждение, если возвращаемое значение игнорируется
(спецификатор атрибута) |
|
[[
maybe_unused
]]
(C23)
|
подавляет предупреждения компилятора о неиспользуемых сущностях, если таковые имеются
(спецификатор атрибута) |
|
указывает, что функция не возвращает управление
(спецификатор атрибута) |
|
[[
unsequenced
]]
(C23)
|
указывает, что функция является статической, без побочных эффектов, идемпотентной и независимой
(спецификатор атрибута) |
[[
reproducible
]]
(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 |