Enumerations

From Appmethod Topics
Jump to: navigation, search

Go Up to Enumerations Index

An enumeration data type is used to provide mnemonic identifiers for a set of integer values. For example, the following declaration:

enum days { sun, mon, tues, wed, thur, fri, sat } anyday;

establishes a unique integral type, enum days, a variable anyday of this type, and a set of enumerators (sun, mon,...) with constant integer values.

The -b compiler switch controls the "Treat Enums As Ints" option. When this switch is used, the compiler allocates a whole word (a four-byte int) for enumeration types (variables of type enum). The default is ON (meaning enums are always ints) if the range of values permits, but the value is always promoted to an int when used in expressions. The identifiers used in an enumerator list are implicitly of type signed char, unsigned char, or int, depending on the values of the enumerators. If all values can be represented in a signed or unsigned char, then that is the type of each enumerator.

In C, a variable of an enumerated type can be assigned any value of type int - no type checking beyond that is enforced. In C++, a variable of an enumerated type can be assigned only one of its enumerators. That is:

anyday = mon;       // OK
anyday = 1;         // illegal, even though mon == 1

The identifier days is the optional enumeration tag that can be used in subsequent declarations of enumeration variables of type enum days:

enum days payday, holiday; // declare two variables

In C++, you can omit the enum keyword if days is not the name of anything else in the same scope.

As with struct and union declarations, you can omit the tag if no further variables of this enum type are required:

enum { sun, mon, tues, wed, thur, fri, sat } anyday;
/* anonymous enum type */

The enumerators listed inside the braces are also known as enumeration constants. Each is assigned a fixed integral value. In the absence of explicit initializers, the first enumerator sun is set to zero, and each succeeding enumerator is set to one more than its predecessor (mon = 1, tues = 2, and so on). See Enumeration constants for more on enumeration constants.

With explicit integral initializers, you can set one or more enumerators to specific values. Any subsequent names without initializers will then increase by one. For example, in the following declaration:

/* Initializer expression can include previously declared enumerators */
enum coins { penny = 1, tuppence, nickel = penny + 4, dime = 10,
             quarter = nickel * nickel } smallchange;

tuppence would acquire the value 2, nickel the value 5, and quarter the value 25.

The initializer can be any expression yielding a positive or negative integer value (after possible integer promotions). These values are usually unique, but duplicates are legal.

enum types can appear wherever int types are permitted.

enum days { sun, mon, tues, wed, thur, fri, sat } anyday;
enum days payday;
typedef enum days DAYS;
DAYS *daysptr;
int i = tues;
anyday = mon;        // OK
*daysptr = anyday;   // OK
mon = tues;          // ILLEGAL: mon is a constant

Enumeration tags share the same name space as structure and union tags. Enumerators share the same name space as ordinary variable identifiers:

int mon = 11;
{
   enum days { sun, mon, tues, wed, thur, fri, sat } anyday;
   /* enumerator mon hides outer declaration of int mon */
   struct days { int i, j;};   // ILLEGAL: days duplicate tag
   double sat;                 // ILLEGAL: redefinition of sat
}
mon = 12;                      // back in int mon scope

In C++, enumerators declared within a class are in the scope of that class.

In C++ it is possible to overload most operators for an enumeration. However, because the =, [ ], ( ), and -> operators must be overloaded as member functions, it is not possible to overload them for an enum. See the example on how to overload the postfix and prefix increment operators.