要使用 GCC 在 C 中执行此操作-Wenum-compare
(如果启用,则默认启用-Wall
),您必须在将枚举常量传递给函数之前对其进行比较,以获得所需的诊断。
-Wenum-比较
警告不同枚举类型的值之间的比较。在 C++ 中,条件表达式中的枚举不匹配也会被诊断出来,并且默认情况下会启用警告。在 C 中,此警告由 -Wall 启用。
http://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html
为了在我们调用函数时自动发生这种比较,我们可以将函数包装在宏中。为了可读性,我还定义了一个宏 SAFE_ENUM,它对枚举常量执行无害的比较(这是在尝试将错误的枚举常量传递给foo
or时最终触发警告的原因bar
)。
/**
SAFE_ENUM: evaluate an enumeration constant safely
TYPE: the enumeration type
VAL: the enumeration constant to evaluate
*/
#define SAFE_ENUM(TYPE, VAL) ((VAL) == (TYPE)0 ? (VAL) : (VAL))
typedef enum
{
REG8_DEFAULT,
REG8_A,
REG8_B,
REG8_C
} Reg8;
typedef enum
{
REG16_DEFAULT,
REG16_A,
REG16_B,
REG16_C
} Reg16;
void foo(Reg8 reg8)
#define foo(reg8) foo(SAFE_ENUM(Reg8, reg8))
{
printf("%s called with value %d\n", __func__, reg8);
}
void bar(Reg16 reg16)
#define bar(reg16) bar(SAFE_ENUM(Reg16, reg16))
{
printf("%s called with value %d\n", __func__, reg16);
}
int main(void)
{
foo(REG8_A); // ok
bar(REG16_A); // ok
foo(REG16_B); // warning
bar(REG8_B); // warning
Reg16 a_reg16 = 42;
foo(a_reg16); // warning: foo requires a Reg8 but you gave it a Reg16
}