Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 403
Tom Avatar asked Jan 31 '13 21:01

Tom


People also ask

How do you create an unsigned enum?

You can force it to be unsigned by including a value large enough that it cannot fit in an int (per specification).

Is enum int or unsigned int?

An enum type is represented by an underlying integer type. The size of the integer type and whether it is signed is based on the range of values of the enumerated constants. In strict C89 or C99 mode, the compiler allows only enumeration constants with values that will fit in "int" or "unsigned int" (32 bits).


1 Answers

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;
like image 87
Carl Norum Avatar answered Sep 21 '22 15:09

Carl Norum