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 是一个 identifier ,而 argument-list 是一个括号、方括号和大括号保持平衡的标记序列( balanced-token-sequence )。
说明
属性为实现定义的语言扩展提供了统一的标准语法,例如 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)
|
表示允许使用带有此属性的名称或实体,但出于某些
原因
不鼓励使用
(属性说明符) |
[[
fallthrough
]]
(C23)
|
表示从前一个 case 标签直落是故意的,不应被会对直落发出警告的编译器诊断
(属性说明符) |
|
鼓励编译器在返回值被丢弃时发出警告
(属性说明符) |
|
[[
maybe_unused
]]
(C23)
|
抑制编译器对未使用实体的警告(如果有)
(属性说明符) |
|
表示函数不会返回
(属性说明符) |
|
[[
unsequenced
]]
(C23)
|
表示函数是无状态的、无副作用的、幂等的且独立的
(属性说明符) |
[[
reproducible
]]
(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中的属性 |