modernize-macro-to-enum¶
将相邻的宏组替换为无作用域的匿名枚举。使用无作用域的匿名枚举可确保在之前使用宏标记的所有地方,都可以安全地使用枚举器名称。
此检查可用于在以下概述的约束条件下,强制执行 C++ 核心准则 Enum.1:优先使用枚举而不是宏。
要替换的潜在宏必须满足以下约束条件
宏只能扩展为整型字面量标记或字面量标记的表达式。表达式可以包含任何一元运算符
-
、+
、~
或!
,任何二元运算符,
、-
、+
、*
、/
、%
、&
、|
、^
、<
、>
、<=
、>=
、==
、!=
、||
、&&
、<<
、>>
或<=>
,三元运算符?:
及其 GNU 扩展。括号表达式也会被识别。这识别了大多数有效的表达式。特别是,使用sizeof
运算符的表达式不会被识别。宏必须在连续的源文件行上定义,或者它们之间只有注释行。
宏必须全部定义在同一个源文件中。
宏不能在条件编译块中定义。(条件包含保护不受此约束的限制。)
宏不能与其他预处理器指令相邻定义。
宏不能在任何条件预处理指令中使用。
宏不能用作其他宏的参数。
宏不能被取消定义。
宏必须在顶级定义,而不是在任何声明或定义中。
每个满足上述约束条件的宏集群都被认为是一组适合用匿名枚举替换的值。从那里,开发人员可以给匿名枚举命名,并继续重构到作用域枚举(如果需要)。在宏定义所在行或后续宏定义之间存在的注释会在输出中保留。提供的替换不会假设任何格式,尽管 clang-tidy 可以选择性地格式化所有修复。
警告
初始化表达式被认为是枚举的有效初始化器。C 要求枚举值适合 int
,但这可能不适用于某些可接受的常量表达式。例如,当 int
的大小为 32 位时,1 << 40
不适合 int
。
示例
#define RED 0xFF0000
#define GREEN 0x00FF00
#define BLUE 0x0000FF
#define TM_NONE (-1) // No method selected.
#define TM_ONE 1 // Use tailored method one.
#define TM_TWO 2 // Use tailored method two. Method two
// is preferable to method one.
#define TM_THREE 3 // Use tailored method three.
变为
enum {
RED = 0xFF0000,
GREEN = 0x00FF00,
BLUE = 0x0000FF
};
enum {
TM_NONE = (-1), // No method selected.
TM_ONE = 1, // Use tailored method one.
TM_TWO = 2, // Use tailored method two. Method two
// is preferable to method one.
TM_THREE = 3 // Use tailored method three.
};