Search code examples
cenumsstandardsmisra

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


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?


Solution

  • 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;