命名空间
变体
操作

属性说明符序列(自 C23 起)

来自 cppreference.com
< c‎ | 语言

引入针对类型、对象、表达式等的实现定义属性。

内容

[编辑] 语法

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

形式上,语法是

[[ attribute-list ]] (自 C23 起)

其中 attribute-list 是零个或多个以逗号分隔的 attribute-token s

标准属性 (1)
attribute-prefix :: 标识符 (2)
standard-attribute ( argument-list (可选) ) (3)
attribute-prefix :: 标识符 ( argument-list (可选) ) (4)

其中 attribute-prefix 是一个 标识符,而 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__,其含义不会改变。

[[已弃用]](C23)
[[已弃用("原因")]](C23)
表示使用此属性声明的名称或实体是被允许的,但由于某些 原因 而被劝阻使用。
(属性说明符)[编辑]
[[穿透]](C23) 表示从上一个 case 标签穿透是故意的,编译器不应该对穿透发出警告。
(属性说明符)[编辑]
[[不舍弃]](C23)
[[不舍弃("原因")]](C23)
鼓励编译器在舍弃返回值时发出警告。
(属性说明符)[编辑]
[[可能未使用]](C23) 抑制编译器对未使用实体的警告(如果有)。
(属性说明符)[编辑]
[[无返回值]](C23)
[[_Noreturn]](C23)(已弃用)
表示函数不会返回。
(属性说明符)[编辑]
[[无序]](C23) 表示函数是无状态、无副作用、幂等的,并且是独立的。
(属性说明符)[编辑]
[[可重复]](C23) 表示函数是无副作用的,并且是幂等的。
(属性说明符)[编辑]

[编辑] 属性测试

__has_c_attribute( attribute-token )

检查是否存在由 attribute-token 命名的属性标记。

对于标准属性,它将扩展到该属性添加到工作草案中的年份和月份(参见下表),供应商特定属性的存在由非零整数常量决定。

__has_c_attribute 可以扩展到 #if #elif 的表达式中。它被 #ifdef #ifndefdefined 视为已定义的宏,但不能在其他任何地方使用。

attribute-token 属性 标准
已弃用 [[已弃用]] 201904L (C23)
穿透 [[贯穿]] 201904L (C23)
可能未使用 [[可能未使用]] 201904L (C23)
不舍弃 [[不丢弃]] 202003L (C23)
noreturn
_Noreturn
[[noreturn]]
[[_Noreturn]]
202202L (C23)
无序 [[无序]] 202207L (C23)
可重复 [[可重现]] 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 中的属性