Is there a way to make an enum unsigned in the C90 standard? (MISRA-C 2004 compliant)

Tom picture Tom · Jan 31, 2013 · Viewed 13.5k times · Source

I'm trying to find a way to make an enum "unsigned".

enum{
     x1 = 0,
     x2,
     x3
};
uint8_t = x2; /* <--- PC-LINT MISRA-C 2004 will complain about mixing signed and unsigned here */

Of course, I can add a typecast to get rid of the error, that is time consuming and error prone.

uint8_t = (uint8_t)x2; /* This works, but is a lot of extra work over the course of 1000s of lines of code*/

So, is there a way to make a specific enum unsigned that MISRA-C 2004 will like?

Answer

Carl Norum picture Carl Norum · Jan 31, 2013

There is no standard C way to control the type chosen for an enum. You can do it in implementation specific ways sometimes, like by adding a value to the enumeration that forces the type to be unsigned:

enum {
  x1,
  x2,
  x3,
  giant_one_for_forcing_unsigned = 0x80000000;
};

But that's not even standard C, either (since the value provided won't fit in an int). Unfortunately, you're pretty much out of luck. Here's the relevant bit from the standard:

6.7.2.2 Enumeration specifiers, paragraph 4

Each enumerated type shall be compatible with char, a signed integer type, or an unsigned integer type. The choice of type is implementation-defined, but shall be capable of representing the values of all the members of the enumeration. The enumerated type is incomplete until immediately after the } that terminates the list of enumerator declarations, and complete thereafter.

You might be better off using #define rather than enum to make your constants:

#define x1 0U
#define x2 1U
#define x3 2U

uint8_t x = x2;