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 }
-Werror is a compiler flag that causes all compiler warnings to be treated as errors. Developers who enable -Werror are making a statement: we care about our code base, and we won't accept warnings here.
You can use the -Werror compiler flag to turn all or some warnings into errors.
By default, Fuchsia C/C++ code compiles with the flag -Wconversion , which prohibits implicit type conversions that may alter a value.
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 }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With