C++ 中的属性
属性是 C++ 中现代化的方法,用于在代码在不同编译器上运行时标准化某些内容。属性用于提供一些额外的信息,这些信息用于强制条件(约束)、优化以及根据需要执行特定的代码生成。
这就像编译器的使用手册,用于执行一些操作,从而提高代码的性能。属性首次出现在 C++ 11 中,从那时起就成为编程语言的重要组成部分。此外,每个版本都会不断进行一些修改,以使其更强大、更好。
让我们看看如何在 C++ 中定义属性。
对于不同版本的 C++,定义属性的语法不同。
在 C++ 11 中创建属性的语法:
[[attribute-list]]
在 C++ 17 中创建属性的语法:
[[using attribute-namespace : attribute_list]]
在 C++ 20 中创建属性的语法(即将发布):
[[contract-attriubute-token contract-level-identifier : expression]]
您可以对变量、函数、类使用许多属性。
现在,既然我们知道什么是属性,它们是如何工作的以及如何定义的,让我们看看 C++ 中可用的不同标准属性。
C++ 11 中引入的属性
noreturn - 此属性用于告诉编译器该函数不返回值。
语法
[[noreturn]]
示例
[[noreturn]] void f();
此函数不会返回值,甚至不返回 void。
在 C++ 中使用 noreturn 属性时,如果发生错误并且流程没有返回到调用代码(例如,无限循环或任何错误),则会使编译器能够返回警告。
carries_dependency - 用于定义所有发布-消费依赖项,并允许编译器通过不执行不必要的内存消耗指令来进行优化。
语法
[[carries_dependency]]
主要用于函数或参数的声明中,以声明依赖关系。
deprecated - 用于定义代码中已弃用的实体。允许使用此已弃用的实体,但不建议使用。
语法
[[deprecated]] [[deprecated (reason)]]
原因是一个字符串,说明弃用的原因,并为已弃用的实体提供替代方案。
可以弃用的实体包括类、结构体、联合体、typedef-name、静态成员、函数、命名空间、枚举。
fallthrough - 用于指示编译器从下一个 case 的贯穿是故意的,因此编译器不会警告贯穿。
语法
[[fallthrough]]
fallthrough 只能与 switch 一起使用,因为它的下一个 case 已定义。
nodiscard - 用于一个函数,该函数将返回一个枚举,该枚举将从丢弃的值表达式而不是强制转换为 void 调用中调用。编译器也将为此发出警告。
语法
[[nodiscard]] [[nodiscard (reason)]] (added in C++ 20)
原因是一个字符串,用于提供不丢弃结果的原因,这将在 C++ 20 中包含。
maybe_unused - 用于告诉编译器抑制或消除在未使用实体的情况下显示的警告。
语法
[[maybe_unused]]
可以声明为 maybe_unused 的实体包括类、结构体、联合体、typedef-name、静态成员、函数、变量、枚举。
likely, unlikely - 用于定义备用路径是否比当前执行更可能或不太可能。
语法
[[likely]] [[unlikely]]
通常应用于更改程序流程的实体,例如标签和语句。
no_unique_address - 用于定义不需要特定地址的数据成员。通常用于非静态数据成员的情况下,定义其内存分配不是必需的。
语法
[[no_unique_address]]
当编译器需要在普通变量和 no_unique_address 变量之间分配内存位置时,这很有用,编译器将优先考虑前者。
Optimize_for_synchronized - 用于定义给定函数的定义必须针对从同步语句调用进行优化。
语法
[[optimize_for_synchronized]]
定义为 optimize_for_synchronized 的函数将避免序列化同步块。
expects - 指定函数执行的函数参数必须满足的条件。
语法
[[expects : condition]]
条件定义了函数执行必须满足的条件。
这些都是从 C++ 11 到 C++ 20 在 C++ 中定义的所有属性。现在,让我们看看为什么这些属性在编程中使用,即建议的属性解决了什么问题?
向代码添加约束 - 在许多情况下,属性会向代码添加含义,使其更有效,并减少额外的精力。
向编译器提供更多优化信息 - 一些属性(如 fallthrough、likely、maybe_used)向编译器提供信息,以便执行特定的优化。
避免警告和错误 - 有时,程序员的逻辑违反了 C++ 的严格规则。在这种情况下,一些属性可以发挥作用,帮助用户避免或抑制即将发生的警告。