Files
2025-10-25 03:02:53 +03:00

337 lines
20 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

[dcl.enum]
# 9 Declarations [[dcl]](./#dcl)
## 9.8 Enumerations [[enum]](enum#dcl.enum)
### 9.8.1 Enumeration declarations [dcl.enum]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L7788)
An enumeration is a distinct type ([[basic.compound]](basic.compound "6.9.4Compound types")) with named
constants[.](#1.sentence-1)
Its name becomes an [*enum-name*](#nt:enum-name "9.8.1Enumeration declarations[dcl.enum]") within its scope[.](#1.sentence-2)
[enum-name:](#nt:enum-name "9.8.1Enumeration declarations[dcl.enum]")
[*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]")
[enum-specifier:](#nt:enum-specifier "9.8.1Enumeration declarations[dcl.enum]")
[*enum-head*](#nt:enum-head "9.8.1Enumeration declarations[dcl.enum]") { [*enumerator-list*](#nt:enumerator-list "9.8.1Enumeration declarations[dcl.enum]")opt }
[*enum-head*](#nt:enum-head "9.8.1Enumeration declarations[dcl.enum]") { [*enumerator-list*](#nt:enumerator-list "9.8.1Enumeration declarations[dcl.enum]") , }
[enum-head:](#nt:enum-head "9.8.1Enumeration declarations[dcl.enum]")
[*enum-key*](#nt:enum-key "9.8.1Enumeration declarations[dcl.enum]") [*attribute-specifier-seq*](dcl.attr.grammar#nt:attribute-specifier-seq "9.13.1Attribute syntax and semantics[dcl.attr.grammar]")opt [*enum-head-name*](#nt:enum-head-name "9.8.1Enumeration declarations[dcl.enum]")opt [*enum-base*](#nt:enum-base "9.8.1Enumeration declarations[dcl.enum]")opt
[enum-head-name:](#nt:enum-head-name "9.8.1Enumeration declarations[dcl.enum]")
[*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3Qualified names[expr.prim.id.qual]")opt [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]")
[opaque-enum-declaration:](#nt:opaque-enum-declaration "9.8.1Enumeration declarations[dcl.enum]")
[*enum-key*](#nt:enum-key "9.8.1Enumeration declarations[dcl.enum]") [*attribute-specifier-seq*](dcl.attr.grammar#nt:attribute-specifier-seq "9.13.1Attribute syntax and semantics[dcl.attr.grammar]")opt [*enum-head-name*](#nt:enum-head-name "9.8.1Enumeration declarations[dcl.enum]") [*enum-base*](#nt:enum-base "9.8.1Enumeration declarations[dcl.enum]")opt ;
[enum-key:](#nt:enum-key "9.8.1Enumeration declarations[dcl.enum]")
enum
enum class
enum struct
[enum-base:](#nt:enum-base "9.8.1Enumeration declarations[dcl.enum]")
: [*type-specifier-seq*](dcl.type.general#nt:type-specifier-seq "9.2.9.1General[dcl.type.general]")
[enumerator-list:](#nt:enumerator-list "9.8.1Enumeration declarations[dcl.enum]")
[*enumerator-definition*](#nt:enumerator-definition "9.8.1Enumeration declarations[dcl.enum]")
[*enumerator-list*](#nt:enumerator-list "9.8.1Enumeration declarations[dcl.enum]") , [*enumerator-definition*](#nt:enumerator-definition "9.8.1Enumeration declarations[dcl.enum]")
[enumerator-definition:](#nt:enumerator-definition "9.8.1Enumeration declarations[dcl.enum]")
[*enumerator*](#nt:enumerator "9.8.1Enumeration declarations[dcl.enum]")
[*enumerator*](#nt:enumerator "9.8.1Enumeration declarations[dcl.enum]") = [*constant-expression*](expr.const#nt:constant-expression "7.7Constant expressions[expr.const]")
[enumerator:](#nt:enumerator "9.8.1Enumeration declarations[dcl.enum]")
[*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]") [*attribute-specifier-seq*](dcl.attr.grammar#nt:attribute-specifier-seq "9.13.1Attribute syntax and semantics[dcl.attr.grammar]")opt
The optional [*attribute-specifier-seq*](dcl.attr.grammar#nt:attribute-specifier-seq "9.13.1Attribute syntax and semantics[dcl.attr.grammar]") in the [*enum-head*](#nt:enum-head "9.8.1Enumeration declarations[dcl.enum]") and
the [*opaque-enum-declaration*](#nt:opaque-enum-declaration "9.8.1Enumeration declarations[dcl.enum]") appertains to the enumeration; the attributes
in that [*attribute-specifier-seq*](dcl.attr.grammar#nt:attribute-specifier-seq "9.13.1Attribute syntax and semantics[dcl.attr.grammar]") are thereafter considered attributes of the
enumeration whenever it is named[.](#1.sentence-3)
A : following
“enum [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3Qualified names[expr.prim.id.qual]")opt [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]")”
within the [*decl-specifier-seq*](dcl.spec.general#nt:decl-specifier-seq "9.2.1General[dcl.spec.general]") of a [*member-declaration*](class.mem.general#nt:member-declaration "11.4.1General[class.mem.general]") is parsed as part of an [*enum-base*](#nt:enum-base "9.8.1Enumeration declarations[dcl.enum]")[.](#1.sentence-4)
[*Note [1](#note-1)*:
This resolves a potential ambiguity between the declaration of an enumeration
with an [*enum-base*](#nt:enum-base "9.8.1Enumeration declarations[dcl.enum]") and the declaration of an unnamed bit-field of enumeration
type[.](#1.sentence-5)
[*Example [1](#example-1)*: struct S {enum E : int {}; enum E : int {}; // error: redeclaration of enumeration}; — *end example*]
— *end note*]
The [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]") in an [*enum-head-name*](#nt:enum-head-name "9.8.1Enumeration declarations[dcl.enum]") is not looked up and is introduced by
the [*enum-specifier*](#nt:enum-specifier "9.8.1Enumeration declarations[dcl.enum]") or [*opaque-enum-declaration*](#nt:opaque-enum-declaration "9.8.1Enumeration declarations[dcl.enum]")[.](#1.sentence-6)
If the [*enum-head-name*](#nt:enum-head-name "9.8.1Enumeration declarations[dcl.enum]") of an [*opaque-enum-declaration*](#nt:opaque-enum-declaration "9.8.1Enumeration declarations[dcl.enum]") contains
a [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3Qualified names[expr.prim.id.qual]"),
the declaration shall be an [explicit specialization](temp.expl.spec "13.9.4Explicit specialization[temp.expl.spec]")[.](#1.sentence-7)
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L7875)
The enumeration type declared with an [*enum-key*](#nt:enum-key "9.8.1Enumeration declarations[dcl.enum]") of only enum is an [*unscoped enumeration*](#def:enumeration,unscoped "9.8.1Enumeration declarations[dcl.enum]"),
and its [*enumerator*](#nt:enumerator "9.8.1Enumeration declarations[dcl.enum]")*s* are [*unscoped enumerators*](#def:enumerator,unscoped "9.8.1Enumeration declarations[dcl.enum]")[.](#2.sentence-1)
The [*enum-key*](#nt:enum-key "9.8.1Enumeration declarations[dcl.enum]")*s* enum class andenum struct are semantically equivalent; an enumeration
type declared with one of these is a [*scoped enumeration*](#def:enumeration,scoped "9.8.1Enumeration declarations[dcl.enum]"),
and its [*enumerator*](#nt:enumerator "9.8.1Enumeration declarations[dcl.enum]")*s* are [*scoped enumerators*](#def:enumerator,scoped "9.8.1Enumeration declarations[dcl.enum]")[.](#2.sentence-2)
The optional [*enum-head-name*](#nt:enum-head-name "9.8.1Enumeration declarations[dcl.enum]") shall not be omitted in the declaration of a scoped enumeration[.](#2.sentence-3)
The [*type-specifier-seq*](dcl.type.general#nt:type-specifier-seq "9.2.9.1General[dcl.type.general]") of an [*enum-base*](#nt:enum-base "9.8.1Enumeration declarations[dcl.enum]") shall name an integral type; any cv-qualification is ignored[.](#2.sentence-4)
An [*opaque-enum-declaration*](#nt:opaque-enum-declaration "9.8.1Enumeration declarations[dcl.enum]") declaring an unscoped enumeration shall
not omit the [*enum-base*](#nt:enum-base "9.8.1Enumeration declarations[dcl.enum]")[.](#2.sentence-5)
The identifiers in an [*enumerator-list*](#nt:enumerator-list "9.8.1Enumeration declarations[dcl.enum]") are declared as
constants, and can appear wherever constants are required[.](#2.sentence-6)
The same identifier shall not appear as
the name of multiple enumerators in an [*enumerator-list*](#nt:enumerator-list "9.8.1Enumeration declarations[dcl.enum]")[.](#2.sentence-7)
An [*enumerator-definition*](#nt:enumerator-definition "9.8.1Enumeration declarations[dcl.enum]") with = gives the associated[*enumerator*](#nt:enumerator "9.8.1Enumeration declarations[dcl.enum]") the value indicated by the[*constant-expression*](expr.const#nt:constant-expression "7.7Constant expressions[expr.const]")[.](#2.sentence-8)
An [*enumerator-definition*](#nt:enumerator-definition "9.8.1Enumeration declarations[dcl.enum]") without = gives the associated[*enumerator*](#nt:enumerator "9.8.1Enumeration declarations[dcl.enum]") the value zero
if it is the first [*enumerator-definition*](#nt:enumerator-definition "9.8.1Enumeration declarations[dcl.enum]"),
and the value of the previous [*enumerator*](#nt:enumerator "9.8.1Enumeration declarations[dcl.enum]") increased by one otherwise[.](#2.sentence-9)
[*Example [2](#example-2)*:
enum { a, b, c=0 };enum { d, e, f=e+2 }; defines a, c, and d to be zero, b ande to be 1, and f to be 3[.](#2.sentence-10)
— *end example*]
The optional [*attribute-specifier-seq*](dcl.attr.grammar#nt:attribute-specifier-seq "9.13.1Attribute syntax and semantics[dcl.attr.grammar]") in an[*enumerator*](#nt:enumerator "9.8.1Enumeration declarations[dcl.enum]") appertains to that enumerator[.](#2.sentence-11)
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L7913)
An [*opaque-enum-declaration*](#nt:opaque-enum-declaration "9.8.1Enumeration declarations[dcl.enum]") is either a redeclaration
of an enumeration in the current scope or a declaration of a new enumeration[.](#3.sentence-1)
[*Note [2](#note-2)*:
An enumeration declared by an[*opaque-enum-declaration*](#nt:opaque-enum-declaration "9.8.1Enumeration declarations[dcl.enum]") has a fixed underlying type and is a
complete type[.](#3.sentence-2)
The list of enumerators can be provided in a later redeclaration
with an [*enum-specifier*](#nt:enum-specifier "9.8.1Enumeration declarations[dcl.enum]")[.](#3.sentence-3)
— *end note*]
A scoped enumeration
shall not be later redeclared as unscoped or with a different underlying type[.](#3.sentence-4)
An unscoped enumeration shall not be later redeclared as scoped and each
redeclaration shall include an [*enum-base*](#nt:enum-base "9.8.1Enumeration declarations[dcl.enum]") specifying the same
underlying type as in the original declaration[.](#3.sentence-5)
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L7928)
If an [*enum-head-name*](#nt:enum-head-name "9.8.1Enumeration declarations[dcl.enum]") contains a[*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3Qualified names[expr.prim.id.qual]"),
the enclosing [*enum-specifier*](#nt:enum-specifier "9.8.1Enumeration declarations[dcl.enum]") or [*opaque-enum-declaration*](#nt:opaque-enum-declaration "9.8.1Enumeration declarations[dcl.enum]") D shall not inhabit a class scope and
shall correspond to one or more declarations nominable
in the class, class template, or namespace
to which the [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3Qualified names[expr.prim.id.qual]") refers ([[basic.scope.scope]](basic.scope.scope "6.4.1General"))[.](#4.sentence-1)
All those declarations shall have the same target scope;
the target scope of D is that scope[.](#4.sentence-2)
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L7940)
Each enumeration defines a type that is different from all other types[.](#5.sentence-1)
Each enumeration also has an [*underlying type*](#def:type,underlying,enumeration "9.8.1Enumeration declarations[dcl.enum]")[.](#5.sentence-2)
The underlying type can be explicitly specified using an [*enum-base*](#nt:enum-base "9.8.1Enumeration declarations[dcl.enum]")[.](#5.sentence-3)
For a scoped enumeration type, the underlying type is int if it is not
explicitly specified[.](#5.sentence-4)
In both of these cases, the underlying type is said to be[*fixed*](#def:type,underlying,fixed "9.8.1Enumeration declarations[dcl.enum]")[.](#5.sentence-5)
Following the closing brace of an [*enum-specifier*](#nt:enum-specifier "9.8.1Enumeration declarations[dcl.enum]"), each
enumerator has the type of its enumeration[.](#5.sentence-6)
If the underlying type is fixed, the type of each enumerator
prior to the closing brace is the underlying
type
and the [*constant-expression*](expr.const#nt:constant-expression "7.7Constant expressions[expr.const]") in the [*enumerator-definition*](#nt:enumerator-definition "9.8.1Enumeration declarations[dcl.enum]") shall be a[converted constant expression](expr.const#def:expression,converted_constant "7.7Constant expressions[expr.const]") of the underlying type[.](#5.sentence-7)
If the underlying
type is not fixed,
the type of each enumerator prior to the closing brace is determined as
follows:
- [(5.1)](#5.1)
If an
initializer is specified for an enumerator, the[*constant-expression*](expr.const#nt:constant-expression "7.7Constant expressions[expr.const]") shall be an[integral constant expression](expr.const#def:expression,integral_constant "7.7Constant expressions[expr.const]")[.](#5.1.sentence-1)
If the expression has
unscoped enumeration type, the enumerator has the underlying type of that
enumeration type, otherwise it has the same type as the expression[.](#5.1.sentence-2)
- [(5.2)](#5.2)
If no initializer is specified for the
first enumerator, its type is an unspecified signed integral type[.](#5.2.sentence-1)
- [(5.3)](#5.3)
Otherwise
the type of the enumerator is the same as that of the
preceding enumerator unless the incremented value is not representable
in that type, in which case the type is an unspecified integral type
sufficient to contain the incremented value[.](#5.3.sentence-1)
If no such type exists, the program
is ill-formed[.](#5.3.sentence-2)
[6](#6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L7982)
An enumeration whose underlying type is fixed is an incomplete type
until immediately after its[*enum-base*](#nt:enum-base "9.8.1Enumeration declarations[dcl.enum]") (if any), at which point it becomes a complete type[.](#6.sentence-1)
An enumeration whose underlying type is not fixed is an incomplete type
until the closing } of its[*enum-specifier*](#nt:enum-specifier "9.8.1Enumeration declarations[dcl.enum]"), at which point it becomes a complete type[.](#6.sentence-2)
[7](#7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L7990)
For an enumeration whose underlying type is not fixed,
the underlying type
is an
integral type that can represent all the enumerator values defined in
the enumeration[.](#7.sentence-1)
If no integral type can represent all the enumerator
values, the enumeration is ill-formed[.](#7.sentence-2)
It is implementation-defined
which integral type is used as the underlying type
except that the underlying type shall not be larger than int unless the value of an enumerator cannot fit in an int orunsigned int[.](#7.sentence-3)
If the [*enumerator-list*](#nt:enumerator-list "9.8.1Enumeration declarations[dcl.enum]") is empty, the
underlying type is as if the enumeration had a single enumerator with
value 0[.](#7.sentence-4)
[8](#8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L8004)
For an enumeration whose underlying type is fixed, the values of
the enumeration are the values of the underlying type[.](#8.sentence-1)
Otherwise,
the values of the enumeration are the values representable by
a hypothetical integer type with minimal width M such that all enumerators can be represented[.](#8.sentence-2)
The width of the smallest bit-field large enough to hold all the values of the
enumeration type is M[.](#8.sentence-3)
It is possible to define an enumeration that has values not defined by
any of its enumerators[.](#8.sentence-4)
If the [*enumerator-list*](#nt:enumerator-list "9.8.1Enumeration declarations[dcl.enum]") is empty, the
values of the enumeration are as if the enumeration had a single enumerator with
value 0[.](#8.sentence-5)[82](#footnote-82 "This set of values is used to define promotion and conversion semantics for the enumeration type. It does not preclude an expression of enumeration type from having a value that falls outside this range.")
[9](#9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L8024)
An enumeration has
the same size,
value representation, and
alignment requirements ([[basic.align]](basic.align "6.8.3Alignment"))
as its underlying type[.](#9.sentence-1)
Furthermore, each value of an enumeration has the same representation
as the corresponding value of the underlying type[.](#9.sentence-2)
[10](#10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L8033)
Two enumeration types are [*layout-compatible enumerations*](#def:layout-compatible,enumeration "9.8.1Enumeration declarations[dcl.enum]") if they have the same underlying type[.](#10.sentence-1)
[11](#11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L8037)
The value of an enumerator or an object of an unscoped enumeration type is
converted to an integer by [integral promotion](conv.prom#def:integral_promotion "7.3.7Integral promotions[conv.prom]")[.](#11.sentence-1)
[*Example [3](#example-3)*:
enum color { red, yellow, green=20, blue };
color col = red;
color* cp = &col;if (*cp == blue) // ... makes color a type describing various colors, and then declarescol as an object of that type, and cp as a pointer to an
object of that type[.](#11.sentence-2)
The possible values of an object of typecolor are red, yellow, green,blue; these values can be converted to the integral values0, 1, 20, and 21[.](#11.sentence-3)
Since enumerations are
distinct types, objects of type color can be assigned only
values of type color[.](#11.sentence-4)
color c = 1; // error: type mismatch, no conversion from int to colorint i = yellow; // OK, yellow converted to integral value 1, integral promotion
Note that this implicit enum to int conversion is not provided for a scoped enumeration:enum class Col { red, yellow, green };int x = Col::red; // error: no Col to int conversion Col y = Col::red;if (y) { } // error: no Col to bool conversion
— *end example*]
[12](#12)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L8069)
The name of each unscoped enumerator is also bound
in the scope that immediately contains the [*enum-specifier*](#nt:enum-specifier "9.8.1Enumeration declarations[dcl.enum]")[.](#12.sentence-1)
An unnamed enumeration
that does not have a typedef name for linkage purposes ([[dcl.typedef]](dcl.typedef "9.2.4The typedef specifier")) and
that has a first enumerator
is denoted, for linkage purposes ([[basic.link]](basic.link "6.7Program and linkage")),
by its underlying type and its first enumerator;
such an enumeration is said to have
an enumerator as a name for linkage purposes[.](#12.sentence-2)
[*Note [3](#note-3)*:
Each unnamed enumeration with no enumerators is a distinct type[.](#12.sentence-3)
— *end note*]
[*Example [4](#example-4)*: enum direction { left='l', right='r' };
void g() { direction d; // OK d = left; // OK d = direction::right; // OK}enum class altitude { high='h', low='l' };
void h() { altitude a; // OK a = high; // error: high not in scope a = altitude::low; // OK} — *end example*]
[82)](#footnote-82)[82)](#footnoteref-82)
This set of values is used to define promotion and
conversion semantics for the enumeration type[.](#footnote-82.sentence-1)
It does not preclude an
expression of enumeration type from having a value that falls outside
this range[.](#footnote-82.sentence-2)