C++17 关键新特性介绍及代码讲解 (5) — attributes for namespaces and enumerators
一句话概括:
在定义 namespace
、enum
时,允许指定 attributes。 这里的 attributes 指: 具体所使用的C++编译器所提供的语言扩展属性。
gcc 提供的 attributes : 参见 [gcc Attribute Syntax]
clang 提供的 attributes : 参见 [Clang 15.0.0git documentation ATTRIBUTES IN CLANG]
为 enumerators 设置 attributes
在定义 enum
时,我们可以单独为每个 enumerator 指定 attributes, 比如 gnu::deprecated
:
enum class ARM_CPU {
cpu_R5 [[gnu::unavailable("end_of_life")]], // 'deprecated' enumerator.
cpu_R8,
};
上面代码中, gnu::deprecated
attribute 的作用:早期的项目代码,定义了一个代表 CPU 类型的 enum class: ARM_CPU
,
供项目中选择CPU类型的代码引用。后来随着项目的发展,cpu_R5
这种 CPU 类型面临逐步停产,为了对项目中使用到该CPU类型的代码进行清理、修改,
我们可以为 cpu_R5
这个 enumerator 增加一条 attribute: gnu::deprecated
,并且将原因标注为"end_of_life";
然后,在整个项目代码 re-compile 时,引用到cpu_R5
的代码,就会触发编译告警,从而锁定需要清理、修改的代码,以便在将来的版本里彻底去除
cpu_R5
这个enumerator。 比如,下面代码中的choose_cpu
函数在 re-compile 时,就会触发编译告警:
ARM_CPU choose_cpu() {
return ARM_CPU::cpu_R5;
}
gcc编译告警:
warning: ‘ARM_CPU::cpu_R5’ is deprecated: end_of_life
完整 demo 代码参见 gitee.com 上的公开代码仓库 : [attributes_for_namespaces_and_enumerators]
为 namespace 设置 attributes
为 namespace 设置的 attributes,可以对在namespace中定义的类型、函数、变量生效。
目前可以用于 namespace 的 attibutes 种类还很少。
我们举一个 abi_tag
的例子,完整 demo 代码参见 gitee.com 上的公开代码仓库 : [attributes_for_namespaces_and_enumerators]
先简单提一下,ABI 即 Application Binary Interface 的缩写,代表二进制代码(比如各种libraray),在目标OS/硬件平台上,被
OS/application/library 调用和访问的接口。ABI 可以看做同编译器/OS 强相关的一种 “访问协议”。
例如,在Linux 上,各开发者的 application 链接、运行时,就是通过 ABI 访问各个 library;所以,各个 library 提供稳定的 ABI 很重要,
这样才能保证 library 更新后,各个 aaplication 的开发者不用 re-build 所有的 application 源代码:只要 library 提供的 ABI
没有改变、且没有影响 application 的源代码级别的 API 更新,所有 application 还是可以继续调用更新后的 library 运行,即各个 application
可以对 library 的更新不感知。
更详细的 ABI 介绍,参见StackOverflow上的这篇问答: [What is an application binary interface (ABI)?]
我们回到 abi_tag 的使用举例:
以 Linux Ubuntu 20.04 作为我们的开发和运行环境。我们有一个数据结构 Box,最初的定义是 2D 的 Box,即只具备 length/width 两个
成员变量,代码如下:
namespace BasicShape {
struct Box {
Box(int l