Anenumerated type is a distincttype whose value is a value of itsunderlying type (see below), which includes the values of explicitly named constants (enumeration constants).
Contents |
Enumerated type is declared using the followingenumeration specifier as thetype-specifier in thedeclaration grammar:
enumattr-spec-seq (optional)identifier (optional){enumerator-list} | (1) | ||||||||
enumattr-spec-seq (optional)identifier (optional):type{enumerator-list} | (2) | (since C23) | |||||||
whereenumerator-list is a comma-separated list(with trailing comma permitted)(since C99) ofenumerator, each of which has the form:
| enumeration-constantattr-spec-seq (optional) | (1) | ||||||||
enumeration-constantattr-spec-seq (optional)=constant-expression | (2) | ||||||||
where
| identifier,enumeration-constant | - | identifiers that are introduced by this declaration |
| constant-expression | - | integer constant expressionwhose value is representable as a value of typeint(until C23).If the enumeration has a fixed underlying type, representable as a value oftype(since C23) |
| attr-spec-seq | - | (C23)optional list ofattributes,
|
As withstruct orunion, a declaration that introduced an enumerated type and one or more enumeration constants may also declare one or more objects of that type or type derived from it.
enum color{ RED, GREEN, BLUE} c= RED,*cp=&c;// introduces the type enum color// the integer constants RED, GREEN, BLUE// the object c of type enum color// the object cp of type pointer to enum color
Eachenumeration-constant that appears in the body of an enumeration specifier becomes aninteger constantwith typeint(until C23) in the enclosing scope and can be used whenever integer constants are required (e.g. as a case label or as a non-VLA array size).
During the processing of each enumeration constant in the enumerator list, the type of the enumeration constant shall be:
A signed integer type is chosen if the previous enumeration constant being added is of signed integer type. An unsigned integer type is chosen if the previous enumeration constant is of unsigned integer type. If there is no suitably sized integer type described previous which can represent the new value, then the enumeration has no type which is capable of representing all of its values. | (since C23) |
Ifenumeration-constant is followed by= constant-expression, its value is the value of that constant expression. Ifenumeration-constant is not followed by= constant-expression, its value is the value one greater than the value of the previous enumerator in the same enumeration. The value of the first enumerator (if it does not use= constant-expression) is zero.
enum Foo{ A, B, C=10, D, E=1, F, G= F+ C};// A=0, B=1, C=10, D=11, E=1, F=2, G=12
Theidentifier itself, if used, becomes the name of the enumerated type in the tagsname space and requires the use of the keyword enum (unless typedef'd into the ordinary name space).
enum color{ RED, GREEN, BLUE};enum color r= RED;// OK// color x = GREEN; // Error: color is not in ordinary name spacetypedefenum color color_t;color_t x= GREEN;// OK
Each enumerated typewithout a fixed underlying type(since C23) iscompatible with one of:char, a signed integer type, or an unsigned integer type(excludingbool and the bit-precise integer types)(since C23). It is implementation-defined which type is compatible with any given enumerated type, but whatever it is, it must be capable of representing all enumerator values of that enumeration.For all enumerations with a fixed underlying type, the enumerated type is compatible with the underlying type of the enumeration.(since C23)
The enumeration member type for an enumerated type without fixed underlying type upon completion is:
| (since C23) |
| All enumerations have an underlying type. The underlying type can be explicitly specified using an enum-type-specifier and is its fixed underlying type. If it is not explicitly specified, the underlying type is the enumeration’s compatible type, which is either a signed or unsigned integer type, orchar. | (since C23) |
Enumerated types are integer types, and as such can be used anywhere other integer types can, including inimplicit conversions andarithmetic operators.
enum{ ONE=1, TWO} e;long n= ONE;// promotiondouble d= ONE;// conversione=1.2;// conversion, e is now ONEe= e+1;// e is now TWO
Unlikestruct orunion, there are no forward-declared enums in C:
enum Color;// Error: no forward-declarations for enums in Cenum Color{ RED, GREEN, BLUE};
Enumerations permit the declaration of named constants in a more convenient and structuredfashion than does#define; they are visible in the debugger, obey scope rules, and participate in the type system.
#define TEN 10struct S{int x: TEN;};// OK
or
enum{ TEN=10};struct S{int x: TEN;};// also OK
Since C23constexpr can be used for the same purpose:
constexprint TEN=10;struct S{int x: TEN;};// also OK
Moreover, as astruct orunion does not establish its scope in C, an enumeration type and its enumeration constants may be introduced in the member specification of the former, and their scope is the same as of the former, afterwards.
struct Element{int z;enum State{ SOLID, LIQUID, GAS, PLASMA} state;} oxygen={8, GAS}; // type enum State and its enumeration constants stay visible here, e.g.void foo(void){enum State e= LIQUID;// OKprintf("%d %d %d ", e, oxygen.state, PLASMA);// prints 1 2 3}
Output:
List of cable stations: FOX: 11 HBO: 22 MAX: 30
C++ documentation forenumeration declaration |