Programming Pointers
Enumerations are integers, except when they're not
Dan Saks
8/18/2008 3:45 PM EDT
I recently explained that although both C and C++ provide void * as the generic data pointer type, each language treats the type a little differently.1 For any object type T, both C and C++ let you implicitly convert an object of type T * to void *. (An implicit conversion is one that doesn't require a cast.) However, only C lets you implicitly convert in the opposite direction--from void * to T *.
There's a similar disparity in the way the two languages treat enumeration values. Both C and C++ let you implicitly convert an enumeration value into an int. However, only C lets you implicitly convert an int into an enumeration.
For example, consider these enumeration definitions:
enum day
{
day_begin,
Sun = day_begin, Mon, Tue, ... , Sat,
day_end
};
typedef enum day day;
enum month
{
month_begin,
Jan = month_begin, Feb, Mar, ... , Dec,
month_end
};
typedef enum month month;
The identifier appearing immediately after the keyword enum is a tag, not a type. I typically define a type name with the same spelling as each tag and then just use the type name.2 I often define additional _begin and _end enumeration constants to facilitate writing loops, like the one you'll see shortly.3
In C, each enumeration constant has type int and each enumeration type is compatible with some integer type. (The integer types include all three character types--plain, signed, and unsigned.) The choice of compatible type is implementation-defined. The C standard grants the freedom to use different integer types to represent different enumeration types, but most compilers just use int to represent all enumeration types.
Treating enumerations as just integers leads to some useful behaviors. For example, C lets you apply all the usual integer operations to enumerations, so you can easily write loops that iterate over a range of enumeration values, as in:
day d;
for (d = day_begin; d != day_end; ++d)
...
Unfortunately, C also lets you do highly questionable things with enumerations such as:
day d;
month m;
d = Dec; // assign a month to a day
m = 31; // assign an arbitrary int to a month
if (d < m) // compare a day with a month
...





betaylor73
8/30/2008 12:35 AM EDT
Small nit...
You include the following snippet in the article:
enum month
{
month_begin,
Jan = month_end, Feb, Mar, ... , Dec,
month_end
};
Shouldn't this instead be:
enum month
{
month_begin,
Jan = month_begin, Feb, Mar, ... , Dec,
month_end
};
Sign in to Reply
ESD editorial staff: SRambo
10/7/2008 12:33 PM EDT
betaylor73,
Thanks for catching that. We've fixed it now.
--Susan Rambo
Managing editor
Embedded Systems Design
Sign in to Reply