'Define data type of enum in C for memory

I could not find a direct answer to this but is it possible to force a certain kind of data type for an enum in C ?

e.g I have an enum for a state machine that will only hold some of the states, so for memory and perfomance issues it would be great to define an enum as a byte or a shorter data type. Is there any way to provide this behaviour in C or even in the Arduino IDE ?

Any help is appreciated



Solution 1:[1]

The C standard says that enumeration constants, that is the "members" of the enum, must be compatible with type int. But the enumeration variable itself is allowed to be of other integer types. If you think this doesn't make any sense, it is because it doesn't: the C standard is irrational when it comes to enums.

As for how to pick which integer type an enumeration variable corresponds to, that's unfortunately a decision made by the compiler, not the programmer. On an 8-bit Atmel, an enum variable is either 8 or 16 bits.

Several compilers gives an option to set the size of an enum through non-standard compiler options. To use such features might not be a good idea regardless, as that would make the code non-portable.

However, regardless of the size of an enum, the compiler may (and likely will) optimize expressions where the enum is present, just as it may optimize any expression containing small integer types to not use int for the calculation, as the C standard otherwise mandates through integer promotion.

In case you have very extreme performance requirements, don't use enums, but uint8_t. But if you had extreme performance requirements, then you wouldn't use a hobbyist 8-bit MCU in the first place! So it turns out that your concern is a non-issue.

Go ahead and use enum and let the compiler worry about optimizations.

Solution 2:[2]

As pointed before enum constants are basically integer constants. They do not take space themself, they are not listed somewhere in the executable code.

However if you use enum type for defining a variable, then the variable probably takes as much space as an int variable. If you need to save this space you can use any other integer type able to store the necessary range. For example, instead of:

enum state {S1, S2, S3, S4};

enum state stack[1000];
...
stack[i] = S2;
... 

you can write:

enum state {S1, S2, S3, S4};
typedef unsigned char my_state_type;

my_state_type stack[1000];
...
stack[i] = S2;
...

Solution 3:[3]

Enums are not "stored" as variables use memory locations. Enums are used in statements. These statements are compiled and in the compiled result (machine code, assembler), the enums are replaced with their value. For example, an enum constant named MY_ENUM1 with value 1 will be replaced in the assembler as

    mov ax, 1

Hence they will take up the smallest amount of memory as is required for the instruction operand.

Solution 4:[4]

It looks to me as if the main value of enums in C is more descriptive code that is presumably easier to read and maintain. There does not seem to be any real benefit to using an enum versus using a bunch of #define statements. Even declaring a variable of type enum color, say my_hue, the compiler, gcc at least, does not show an error if you assign an 'invalid' value (-100 or +100) to my_hue. And as an undesirable side effect you have the compiler choosing variable types that do not work in perfectly reasonable loops.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2
Solution 3 Paul Ogilvie
Solution 4 Greg