属性指定符序列(C++11 起)

来自cppreference.com
< cpp‎ | language

为类型、对象、代码等引入实现定义的属性。

[[attr]] [[attr1, attr2, attr3(args)]] [[namespace::attr(args)]] alignas_specifier

正式而言,语法是

[[ attribute-list ]] (C++11 起)
[[ using attribute-namespace : attribute-list ]] (C++17 起)
[[ contract-attribute-token contract-level(可选) identifier(可选) : expression ]] (C++20 起)

其中 attribute-list 是零或更多 attribute 的逗号分隔列表(可选地以指示包展开的省略号 ... 结束)

identifier
attribute-namespace :: identifier
identifier ( argument-list )
attribute-namespace :: identifier ( argument-list )
1) 简单属性,例如 [[noreturn]]
2) 有命名空间的属性,例如 [[gnu::unused]]
3) 有参数的属性,例如 [[deprecated("because")]]
4) 既有命名空间又有参数列表的属性

using: namespace 出现在属性列表开端,且属性列表中无其他属性能指定命名空间:则指定于 using 的命名空间应用到它们全部:

[[using CC: opt(1), debug]] // 同 [[CC::opt(1), CC::debug]]
[[using CC: CC::opt(1)]] // 错误:不能结合 using 和有作用域属性
(C++17 起)

契约属性使用特殊的属性语法。每个契约属性必须在其自身的属性指定符 ([[]]) 中。能应用多个契约属性指定符到同一实体。

(C++20 起)

目录

[编辑] 解释

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

属性可用在 C++ 程序的几乎所有位置,而且可应用于几乎所有事物:到类型、变量、函数、名称、代码块、整个翻译单元,不过每个特定属性仅在实现所容许处合法: [[expect_true]] 可能是只能与 if ,而非与类声明一同使用的属性, [[omp::parallel()]] 可能是应用到代码块或 for 循环,而非到类型 int 等的属性。(注意此二属性是虚构示例,见后述的标准与一些非标准属性)

在声明中,属性可出现在整个声明前,或直接在被声明实体名称之后,这些情况下它们得到结合。多数其他情形中,属性应用于直接前附的实体。

alignas 指定符是属性序列指定符的一部分,尽管它拥有不同语法。它可出现于 [[...]] 属性出现处,并可与它们混合(假定用于容许 alignas 处)

二个连续的方括号记号( [[ )只能出现于引入属性指定符处,或在属性参数内。

void f() {
  int y[3];
  y[[] { return 0; }()] = 1;    // 错误
  int i [[cats::meow([[]])]]; // OK
}

除了下列的标准属性,实现还可以支持任意拥有实现定义行为的非标准属性。所有实现所未知的属性被忽略,且不产生错误。 (C++17 起)

[编辑] 标准属性

C++ 标准仅定义下列属性。

[[noreturn]] 指示函数不返回
[[carries_dependency]] 指示释放消费 std::memory_order 中的依赖链传入和传出该函数。
[[deprecated]](C++14)
[[deprecated("reason")]](C++14)
指示允许使用声明有此属性的名称或实体,但因 reason 不鼓励使用。
[[fallthrough]](C++17) 指示从前一 case 标号落下是有意的,而在落下时警告的编译器不应该诊断。
[[nodiscard]](C++17) 若返回值被舍弃,则鼓励编译器发布警告。
[[maybe_unused]](C++17) 压制编译器在未使用实体上的警告,若存在。
[[likely]](C++20)
[[unlikely]](C++20)
指示编译器应该为通过语句的执行路径比任何其他执行路径更可能或更不可能的情况优化。
[[no_unique_address]](C++20) 指示非静态数据成员不需要拥有不同于其类的所有其他非静态数据成员的地址。
[[expects]](C++20)
[[ensures]](C++20)
[[assert]](C++20)
为函数指定前提条件、后置条件和断言
[[optimize_for_synchronized]](TM TS) 指示应该为来自 synchronized 语句的调用优化该函数定义

[编辑] 示例

[[gnu::always_inline]] [[gnu::hot]] [[gnu::const]] [[nodiscard]]
inline int f(); // 声明 f 带四个属性
 
[[gnu::always_inline, gnu::const, gnu::hot, nodiscard]]
int f(); // 同上,但用单个含有四个属性的属性指定符
 
// C++17:
[[using gnu : const, always_inline, hot]] [[nodiscard]]
int f[[gnu::always_inline]](); // 属性可出现于多个指定符中
 
int f() { return 0; }
 
int main() {}


[编辑] 外部链接

Clang 支持的 C++ 属性