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
    ...


Next:




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



Please sign in to post comment

Navigate to related information

Datasheets.com Parts Search

185 million searchable parts
(please enter a part number or hit search to begin)
Jobs sponsored by

Feedback Form