Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make gcc warn about passing wrong enum to a function

Tags:

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 } 
like image 747
Rocketmagnet Avatar asked Jan 12 '11 13:01

Rocketmagnet


People also ask

What is the job of werror option in GCC?

-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.

How do I make GCC warnings as errors?

You can use the -Werror compiler flag to turn all or some warnings into errors.

Which flag would you pass to your C++ compiler so it warns you about implicit conversions?

By default, Fuchsia C/C++ code compiles with the flag -Wconversion , which prohibits implicit type conversions that may alter a value.


1 Answers

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 } 
like image 200
Brandin Avatar answered Sep 24 '22 21:09

Brandin