Enum enum definition for unsigned int

According to this SO post:
What is the size of an enum in C?


Enumeration types are of type signed int .

I would like to convert the enum definition from signed int to unsigned int .

For example, on my platform, unsigned int is 32 bits wide. I want to create an enumeration:

 typedef enum hardware_register_e { REGISTER_STATUS_BIT = (1U << 31U) } My_Register_Bits_t; 

My compiler complains that the above definition is out of range (which corresponds to signed int ).

How to declare unsigned int enum values?

Change 1:

  • The preference is not to expand to 64 bits (since the code is in the embedded system).
  • Due to skill limitations, C ++ is not allowed for this project. :-(

Edit 2:

  • The compiler is the IAR Embedded Workbench for ARM7.
+7
source share
4 answers

Unfortunately, the ISO C standard (c99 6.4.4.3) indicates that enum constants are of type int . If you compile the above, for example. gcc -W -std=c89 -pedantic , it issues an ISO C restricts enumerator values to range of 'int' [-pedantic] warning ISO C restricts enumerator values to range of 'int' [-pedantic] . Some built-in compilers may not accept code at all.

If your compiler has a sorter, you can work around the problem using

 typedef enum hardware_register_e { REGISTER_STATUS_BIT = -2147483648 /* 1<<31, for 32-bit two complement integers */ } hardware_register_t; 

but it works correctly only if int is 32-bit two types of additions in your architecture. These are all 32-bit and 64-bit architectures that I have ever used or heard.

Edited to add: ARM7 uses a 32-bit two-component int type, so the above should work fine. I recommend that you leave a comment explaining that the actual value is 1<<31 . You never know if anyone is closing code or using another compiler. If the new compiler issues a warning, the comment on the same line should make it trivial to fix it. Personally, I would have wrapped the code conditional, perhaps

 typedef enum hardware_register_e { #ifdef __ICCARM__ REGISTER_STATUS_BIT = -2147483648 /* 1<<31, for 32-bit two complement integers */ #else REGISTER_STATUS_BIT = 1 << 31 #endif } hardware_register_t; 
+2
source

According to this post SO: What is the size of the enum in C? Enumeration types have a type signature type.

An enum type thing may be an int type, but they are not int in C. In gcc 1) enum types are unsigned int by default.

enum constants are int , but enum types are implementation-defined.

In your case, the enum constant is int , but you give it a value that does not match the int value. You cannot have unsigned int enum constants in C, since C says they are int .


<Sub> 1) the gcc implementation defines the documentation of the enum type: "Usually the type is unsigned int if there are no negative values ​​in the enumeration, otherwise int" at http://gcc.gnu.org/onlinedocs/gcc/Structures-unions-enumerations- and-bit_002dfields-implementation.html

sub>

+4
source

Check if your compiler had a parameter or a pragma to do unsigned enumerations. If this is not the case, you just need to use a simple unsigned int (or a fixed-width type like uint32_t ) instead of enum, and #define used to determine the values ​​that it can take.

+1
source

You cannot (at least portable) change the type of enumeration. The standard is clear that the enum constant is of type int . To get rid of the warning, you can use the throw:

 typedef enum hardware_register_e { REGISTER_STATUS_BIT = (int)(1U << 31U) } My_Register_Bits_t; 

Possible alternatives

If this does not have to be in the header, you can use the const object of the required type instead of the enumeration constant:

 const unsigned int REGISTER_STATUS_BIT = (1U << 31); 

Otherwise, you can use define:

 #define REGISTER_STATUS_BIT (1U << 31) 
+1
source

All Articles