achoora
achoora

Reputation: 1350

How to avoid pedantic warnings while using Hexadecimal in Enum?

I have an enum like this

typedef enum {   
    FIRST,  
    SECOND,  
    THIRD = 0X80000001,  
    FOURTH,  
    FIFTH,  
} STATUS;  

I am getting a pedantic warning since I am compiling my files with the option -Wpedantic:

warning: ISO C restricts enumerator values to range of 'int' [-Wpedantic]

I found that it occurs since when I convert the hex value 0X80000001 to integer it exceeds the unsigned integer limits. My purpose is to have continuous hex values as the status in the enum without this warning. I cannot use the macros since this will defy the purpose of having the enums in the first place. What code change will avoid this warning?

Upvotes: 2

Views: 914

Answers (1)

Lundin
Lundin

Reputation: 213711

Enumeration constants are guaranteed to be of the same size as (signed) int. Apparently your system uses 32 bit int, so an unsigned hex literal larger than 0x7FFFFFFF will not fit.

So the warning is not just "pedantic", it hints of a possibly severe bug. Note that -pedantic in GCC does not mean "be picky and give me unimportant warnings" but rather "ensure that my code actually follows the C standard".

It appears that you want to do a list of bit masks or hardware addresses, or some other hardware-related programming. enum is unsuitable for such tasks, because in hardware-related programming, you rarely ever want to use signed types, but always unsigned ones.

If you must have a safe and portable program, then there is no elegant way to do this. C is a language with a lot of flaws, the way enum is defined by the standard is one of them.

One work-around is to use some sort of "poor man's enum", such as:

typedef uint32_t STATUS;

#define THIRD 0X80000001

If you must also have the increased type safety of an enum, then you could possibly use a struct:

typedef struct
{
  uint32_t value;
} STATUS;

Or alternatively, just declare an array of constants and use an enum to define the array index. Probably the cleanest solution but takes a little bit of extra overhead:

typedef enum {   
    FIRST,  
    SECOND,  
    THIRD,  
    FOURTH,  
    FIFTH,  
    STATUS_N
} STATUS; 

const uint32_t STATUS_DATA [STATUS_N] =
{
  0,
  1,
  0X80000001,
  0X80000002,
  0X80000003
};

Upvotes: 4

Related Questions