属性指定符序列(C23 起)
为类型、对象、表达式等引入实现定义的属性。
内容 |
[编辑] 语法
[[
attr< ]]
[[
attr1, attr2, attr3(
args)
]]
[[
attribute-prefix::
attr< (
args)
]]
正式地,语法是
[[ attribute-list ]] |
(C23 起) | ||||||||
其中 attribute-list 是以逗号分隔的零个或多个 attribute-token 的序列
标准属性 | (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}}} |
指示允许使用以此属性声明的名称或实体,但不建议出于某些 reason (属性指定符) |
[[fallthrough]] (C23) |
指示从前一个 case 标签的 fall through 是有意的,编译器在 fall-through 时不应发出警告 (属性指定符) |
鼓励编译器在返回值被丢弃时发出警告 (属性指定符) | |
[[maybe_unused]] (C23) |
抑制编译器关于未使用的实体(如果有)的警告 (属性指定符) |
指示函数不返回 (属性指定符) | |
[[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 属性 (p: TBD)
[编辑] 参见
C++ 文档 关于 属性指定符序列
|
[编辑] 外部链接
1. | GCC 中的属性 |
2. | Clang 中的属性 |