Namespaces
Variants

Attribute specifier sequence (since C23)

From cppreference.net

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

目录

语法

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

正式而言,语法是

[[ 属性列表 ]] (自 C23 起)

其中 attribute-list 是由零个或多个 attribute-token 组成的逗号分隔序列

标准属性 (1)
属性前缀 :: 标识符 (2)
标准属性 ( 参数列表  (可选) ) (3)
属性前缀 :: 标识符 ( 参数列表  (可选) ) (4)

其中 attribute-prefix 是一个 identifier ,而 argument-list 是一个括号、方括号和大括号保持平衡的标记序列( balanced-token-sequence )。

1) 标准属性,例如 [ [ fallthrough ] ]
2) 带有命名空间的属性,例如 [ [ gnu :: unused ] ]
3) 带参数的标准属性,例如 [ [ deprecated ( "reason" ) ] ]
4) 同时具有命名空间和参数列表的属性,例如 [ [ gnu :: nonnull ( 1 ) ] ]

说明

属性为实现定义的语言扩展提供了统一的标准语法,例如 GNU 和 IBM 语言扩展 __attribute__((...)) 、微软扩展 __declspec() 等。

属性几乎可以在C程序中的任何地方使用,并且可以应用于几乎所有对象:类型、变量、函数、名称、代码块、整个翻译单元,但每个特定属性仅在其实现允许的位置有效: [[expect_true]] 可能是只能与 if 语句配合使用的属性,而不能用于类声明。 [[omp::parallel()]] 可能是适用于代码块或 for 循环的属性,但不能用于 int 类型等(注意这两个属性是虚构示例,有关标准及非标准属性的具体内容请参阅下文)

在声明中,属性既可以出现在整个声明之前,也可以直接出现在被声明实体的名称之后,这种情况下它们会被合并。在大多数其他情况下,属性适用于紧邻的前置实体。

两个连续的左方括号标记( [[ )仅能在引入属性说明符时或在属性参数内部出现。

除了下列标准属性外,实现方案可能支持具有实现定义行为的任意非标准属性。所有实现方案未知的属性将被忽略且不会引发错误。

每个 标准属性 都保留用于标准化。也就是说,每个非标准属性都带有一个由实现提供的 属性前缀 ,例如 [[gnu::may_alias]] [[clang::no_sanitize]]

标准属性

只有以下属性由C标准定义。每个名称形式为 attr 的标准属性也可以拼写为 __attr__ ,其含义保持不变。

[[ deprecated ]] (C23) [[ deprecated (" reason ")]] (C23)
表示允许使用带有此属性的名称或实体,但出于某些 原因 不鼓励使用
(属性说明符)
(C23)
表示从前一个 case 标签直落是故意的,不应被会对直落发出警告的编译器诊断
(属性说明符)
[[ nodiscard ]] (C23) [[ nodiscard (" reason ")]] (C23)
鼓励编译器在返回值被丢弃时发出警告
(属性说明符)
(C23)
抑制编译器对未使用实体的警告(如果有)
(属性说明符)
[[ noreturn ]] (C23) [[ _Noreturn ]] (C23) (deprecated)
表示函数不会返回
(属性说明符)
(C23)
表示函数是无状态的、无副作用的、幂等的且独立的
(属性说明符)
(C23)
表示函数是无副作用且幂等的
(属性说明符)

属性测试

__has_c_attribute( 属性标记 )

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

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

__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); // 声明具有三个属性的函数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 属性 (p: TBD)

参见

C++ 文档 关于 Attribute specifier sequence

外部链接

1. GCC中的属性
2. Clang中的属性