In computer programming, an enumerated type is a data type consisting of a set of named values called elements, members, enumeral, or enumerators of the type. The enumerator names are usually identifiers that behave as constants in the language. An enumerated type can be seen as a degenerate tagged union of unit type. A variable that has been declared as having an enumerated type can be assigned any of the enumerators as a value. In other words, an enumerated type defines a set of discrete, mutually exclusive constants that are not generally written to a concrete representation in the computer's memory; compilers and interpreters can represent them arbitrarily without specification from the programmer.

Description For example, the four suits in a deck of playing cards could be represented in an enum called CardSuit, containing four members named CLUBS, DIAMONDS, SPADES, and HEARTS. If a variable v is declared having CardSuit as its data type, one must assign one of those four values to it.

Although the enumerators are usually distinct, some languages may allow the same enumerator to be listed twice in the type's declaration. The names of enumerators are arbitrary and are up to the programmer; an enum named Color could contain the enumerators RED, GREEN, ZEBRA, MISSING, and BACON. In some languages, the declaration of an enumerated type also intentionally defines the total order of its members (e.g., HIGH, MEDIUM and LOW priorities); in others, the enumerators are unordered by default (e.g., ENGLISH, FRENCH, GERMAN and SPANISH supported languages); in others still, an implicit ordering arises from how the compiler chooses to internally represent the enumerators.

Some enumerator types may be built into the language. For example, the Boolean type is often a pre-defined enumeration of the two values false and true. A unit type consisting of a single value may also be defined to represent null. Many languages allow users to define new enumerated types.

Values and variables of an enumerated type are usually implemented with some integer type as the underlying representation. Some languages, especially system programming languages, allow the user to specify the bit combination to be used for each enumerator, which can be useful to efficiently represent sets of enumerators as fixed-length bit strings. In type theory, enumerated types are often regarded as tagged unions of unit types. Since such types are of the form , they may also be written as natural numbers.

Rationale Some early programming languages did not originally have enumerated types. If a programmer wanted a variable, for example , to have a value of RED, the constant RED would be declared and assigned some arbitrary value, usually an integer constant. The constant RED would then be assigned to . Other techniques assigned arbitrary values to strings containing the names of the enumerators.

These arbitrary values were sometimes referred to as magic numbers since there often was no explanation as to how the numbers were obtained or whether their actual values were significant. These magic numbers could make the source code harder for others to understand and maintain.

Enumerated types, on the other hand, make the code more self-documenting. Depending on the language, the compiler could automatically assign default values to the enumerators, thereby hiding unnecessary detail from the programmer. These values may not even be visible to the programmer (see information hiding). Enumerated types can also prevent a programmer from writing illogical code such as performing mathematical operations on the values of the enumerators. If the value of a variable that was assigned an enumerator were to be printed, some programming languages could also print the name of the enumerator rather than its underlying numerical value. A further advantage is that enumerated types can allow compilers to enforce semantic correctness: myColor = TRIANGLE can be forbidden, while myColor = RED should be accepted, even if and are both internally represented with the value .

Conceptually, an enumerated type is similar to a list of nominals (numeric codes), since each possible value of the type is assigned a distinctive natural number. A given enumerated type is thus a concrete implementation of this notion. When order is meaningful and/or used for comparison, then an enumerated type becomes an ordinal type.

Conventions

Programming languages tend to have their own, oftentimes multiple, programming styles and naming conventions. The variable assigned to an enumeration is usually a noun in singular form, and frequently follows either a PascalCase or uppercase convention, while lowercase and others are seen less frequently.

Syntax by language

ALGOL 60 based languages

While ALGOL 60 itself has no enumeration type, several languages descended from it do. In particular, Pascal had a strong influence on the design of Ada.

Pascal In Pascal, an enumerated type can be implicitly declared by listing the values in a parenthesised list: var suit: (clubs, diamonds, hearts, spades); The declaration will often appear in a type synonym declaration, such that it can be used for multiple variables:

type cardsuit = (clubs, diamonds, hearts, spades); card = record suit: cardsuit; value: 1 .. 13; end; var hand: array [ 1 .. 13 ] of card; trump: cardsuit;

The order in which the enumeration values are given matters. An enumerated type is an ordinal type, and the pred and succ functions will give the prior or next value of the enumeration, and ord can convert enumeration values to their integer representation. Standard Pascal does not offer a conversion from arithmetic types to enumerations, however. Extended Pascal offers this functionality via an extended succ function. Some other Pascal dialects allow it via type-casts. Some modern descendants of Pascal, such as Modula-3, provide a special conversion syntax using a method called VAL; Modula-3 also treats BOOLEAN and CHAR as special pre-defined enumerated types and uses ORD and VAL for standard ASCII decoding and encoding.

Pascal style languages also allow enumeration to be used as array index:

var suitcount: array [cardsuit] of integer;

Ada

In Ada, the definition of enumerated types is similar to Pascal, replacing the use of "=" with "is":

type Cardsuit is (clubs, diamonds, hearts, spades);

In addition to Pred, Succ, Val and Pos, Ada also supports simple string conversions via Image and Value.

Similar to C-style languages, Ada allows the internal representation of the enumeration to be specified:

for Cardsuit use (clubs => 1, diamonds => 2, hearts => 4, spades => 8);

Ada also allows the number of bits of the enumeration to be specified in a straightforward manner, unlike C-style languages which have inconsistent support often leading to subtle miscompilation errors:

for Cardsuit'Size use 4; -- 4 bits

Additionally, one can use enumerations as indexes for arrays, like in Pascal, but there are attributes defined for enumerations: Shuffle : constant array(Cardsuit) of Cardsuit := (Clubs => Cardsuit'Succ(Clubs), -- see attributes of enumerations 'First, 'Last, 'Succ, 'Pred Diamonds => Hearts, --an explicit value Hearts => Cardsuit'Last, --first enumeration value of type Cardsuit e.g., clubs Spades => Cardsuit'First --last enumeration value of type Cardsuit e.g., spades );

Like Modula-3, Ada treats Boolean and Character as special pre-defined (in package "Standard") enumerated types. Unlike Modula-3 one can also define own character types:

type Cards is ('7', '8', '9', 'X', 'J', 'Q', 'K', 'A');

PL/I Neither the original PL/I nor ANSI ANSI X3.53–1976 has enumerations, but the IBM Enterprise PL/I has ordinal types.

An ordinal variable cannot be used directly as a subscript or as a DO TO limit. However, The type functions first and last, and the builtin functions binaryvalue, ordinalpred and ordinalsucc, allow it indirectly. DO UPTHRU and DO DOWNTO support ordinals.

define ordinal foo (green,with,envy); declare ix ordinal foo, bar(first(:foo:):last(:foo:)) fixed bin; do i = first(:foo:) to last(:foo:); bar(i)=13; end; do ix=first(:foo:) upthru last(:foo:); i = binaryvalue(ix); bar(i) = bar(i) + 1; end; do ix=first(:foo:) repeat ordinalsucc(ix) until (ix=first(:foo:)) /* stop on wrap around. */; i = binaryvalue(ix); display (bar(i) || ' at ' || ix); end;

C-family languages

C The original K&R dialect of the programming language C had no enumerated types. In C, enumerations are created by explicit definitions (the enum keyword by itself does not cause allocation of storage) which use the enum keyword and are reminiscent of struct and union definitions:

typedef enum { CLUBS, DIAMONDS, HEARTS, SPADES, } CardSuit;

typedef struct { CardSuit suit; short value; } Card;

Card hand; CardSuit trump;

C exposes the integer representation of enumeration values directly to the programmer. Integers and enum values can be mixed freely, and all arithmetic operations on enum values are permitted. It is even possible for an enum variable to hold an integer that does not represent any of the enumeration values. In fact, according to the language specification, the above code will define CLUBS, DIAMONDS, HEARTS, and SPADES as constants of type int, which will only be converted (silently) to enum CardSuit if they are stored in a variable of that type.

C also allows the programmer to choose the values of the enumeration constants explicitly, even without type. The following could be used to define a type that allows mathematical sets of suits to be represented as an enum CardSuit via bitwise logic operations, by representing each suit as a power of two:

enum CardSuit { CLUBS = 1, DIAMONDS = 2, HEARTS = 4, SPADES = 8,

Since C23, the underlying type of an enumeration can be specified by the programmer, with the same syntax as C++. This allows programmers to make optimized enums by choosing a more suitable underlying type.

enum CardSuit : char { CLUBS = 1, DIAMONDS = 2, HEARTS = 4, SPADES = 8,

Enums in C are not scoped or qualified, because C lacks namespacing features. Prior to the introduction of the constexpr keyword in C23, enums were often used to declare compile-time, type-safe constants without use of the C preprocessor:

enum { WINDOW_WIDTH = 600, WINDOW_HEIGHT = 400,

C#

Enumerated types in the C# programming language preserve most of the "small integer" semantics of C's enums. In C#, all enums are classes which extend System.Enum. Some arithmetic operations are not defined for enums, but an enum value can be explicitly converted to an integer (and vice-versa), and an enum variable can have values that were not declared by the enum definition. For example, in the below code:

enum CardSuit { Clubs, Diamonds, Spades, Hearts, }

the expressions CardSuit.Diamonds + 1 and CardSuit.Hearts - CardSuit.Clubs are allowed directly (as it may make sense to step through the sequence of values or ask how many steps there are between two values), but CardSuit.Hearts * CardSuit.Spades is deemed to make less sense and is only allowed if the values are first explicitly converted to integers.

C# also provides the C-like feature of being able to define specific integer values for enumerations. Through this, it is possible to perform binary operations on enumerations, thus treating enumeration values as sets of flags. These flags can be tested using binary operations or with the enum type's builtin HasFlag() method.

The enumeration definition defines names for the selected integer values and is syntactic sugar, as it is possible to assign to an enum variable other integer values that are not in the scope of the enum definition. Alt URL

C++