Enumerations
Enumerations in C are in their most basic sense, a way of creating a meaningful word-based list type.
Enumerations are an alternative to using C preprocessor macros to create words which represent numbers. For example:
If you find yourself doing this, think carefully, would an enumeration be a better way? You can achieve the exact same result with:
Usefullness
Enumerations are commonly used for:
- Creating an list of something (e.g. COLOURS = RED, GREEN, BLUE, …)
- Accessing hardware registers in embedded systems (used for creating meaningful register names).
- Creating state variables (variables which describe a state in a state machine, commonly used with a switch statement)
Syntax
Enums can be defined it two separate ways. The non-typedef way:
Or the typedef way:
Notice when using the first method (non-typedef), everytime you create a variable of the enumeration type you have to write the word enum first. Using the second method (typedef), the enum keyword can be omitted.
By default, the compiler will make the first enumeration value equal to 0, the second equal to 1 and so on. However, you can specify the values you wish the enumerations to take on:
If no value is specified, the compiler will increment by 1
as usual, so in the above case, BLUE = 6
.
Interchangeability
In C, enum types and integer types are normally interchangeable. This can either be a good or bad thing, depending on your viewpoint. C++ allows for stricter type checking with the recently introduced enum class
(strongly-typed enums), which cannot be compared with integer types. Strongly-typed enums also allows you to specify the width of the integer used to store the enumeration.
Optimisation
You are not allowed to take a reference (pointer) to an enumeration (they are not allowed to be lvalues
), while you can with a const int
. This means they can be optimised, while const int
cannot.
The Data Type Of An Enum
The data type of an enumeration is implementation defined. This is what the standard has to say…
The choice of type is implementation-defined, but shall be capable of representing the values of all the members of the enumeration.
Normally you do not care what the width is, as long as it works! However, it certain cases, such as when you are packing an enumeration into a structure and want everything to be of a particular size, you want to exactly specify the enumeration width. You can force an enumeration to be of a larger data type than default by a simple trick of adding a very large number to the end of your enumeration.
Some compilers support directives which will change the default size of an enumeration. For example, in GCC, you can add the compiler flag:
Which will make all enumerations use the smallest width suitable. You can selectively make enumerations smaller by using:
Max Values
There is no compiler syntax or language feature to get the number of elements in an enumeration at compile time. This can be useful information, you may want to do things like:
- Iterate over every value in an enumeration.
- Pick a random value from an enumeration.
- Continue another enumeration from where a previous one left off (to guarantee unique numbers across many enumerations).
A common way of doing this is to add a value to the end of the enumeration calling something like MAX_VALUE
. If it is the last the entry in the enumeration and there are no “gaps” in your enumeration (which is only possible if you manually assign numbers) then MAX_VALUE
will equal the number of members in the enumeration.