gcc doesn't seem to produce a warning with the following code. How can I get it to produce a warning?
typedef enum
{
REG8_A,
REG8_B,
REG8_C
}REG8;
typedef enum
{
REG16_A,
REG16_B,
REG16_C
}REG16;
void function(REG8 reg8)
{
}
int main(void)
{
function(REG16_A); // Should warn about wrong enum
}
For a way to do this in C using GCC's -Wenum-compare
(which is enabled by default if you enable -Wall
), you must perform a comparison on the enumeration constant before you pass it to the function in order to get the desired diagnostic.
-Wenum-compare
Warn about a comparison between values of different enumerated types. In C++ enumeral mismatches in conditional expressions are also diagnosed and the warning is enabled by default. In C this warning is enabled by -Wall.
http://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html
For such a comparison happen to happen automatically when we call the function, we can wrap the function in a macro. For readability I also define a macro SAFE_ENUM that performs a harmless comparison on the enumeration constant (this is what ultimately triggers the warning when trying to pass the wrong enumeration constant to 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
}