GeezerVisonThe World Wide Web, restored to 800 pixels of glory. | ||||||||
| Home|About|Gaming cabinet|Archives|How it works|Starter sites | ||||||||
GeezerVison is showing dlang.org — Enums - D Programming Language Language Reference
Report a bug
If you spot a problem with this page, click here to create a GitHub issue.
Improve this page
Quickly fork, edit online, and submit a pull request for this page.
Requires a signed-in GitHub account. This works well for small changes.
If you'd like to make larger changes you may want to consider using
a local clone.
Enums Contents
EnumDeclaration:
enum Identifier EnumBody
enum Identifier : EnumBaseType EnumBody
AnonymousEnumDeclaration
EnumBaseType:
Type
EnumBody:
{ EnumMembers }
;
EnumMembers:
EnumMember
EnumMember ,
EnumMember , EnumMembers
EnumMember:
EnumMemberAttributesopt Identifier
EnumMemberAttributesopt Identifier = AssignExpression
EnumMemberAttributes:
EnumMemberAttribute
EnumMemberAttribute EnumMemberAttributes
EnumMemberAttribute:
DeprecatedAttribute
UserDefinedAttribute
@ disable
AnonymousEnumDeclaration:
enum : EnumBaseType { EnumMembers }
enum { AnonymousEnumMembers }
AnonymousEnumMembers:
AnonymousEnumMember
AnonymousEnumMember ,
AnonymousEnumMember , AnonymousEnumMembers
AnonymousEnumMember:
EnumMember
EnumMemberAttributesopt Type Identifier = AssignExpression
Enum declarations are used to define a group of constants. Named EnumsNamed enums are used to declare related constants and group them by giving them a unique type. The EnumMembers are declared in the scope of the named enum. The named enum declares a new type, and all the EnumMembers have that type. This defines a new type X which has values X.A = 0, X.B = 1, X.C = 2: enum X { A, B, C } // named enum A variable can be of named enum type. Its default initializer is the first member defined for the enum type. enum X { A = 3, B, C } X x; assert(x == X.A); x |= X.B; assert(x & X.A); The result type of a binary operation on a named enum is defined here. If the EnumBaseType is not explicitly set, and the first EnumMember has an AssignExpression, it is set to the type of that AssignExpression. Otherwise, it defaults to type int.
enum Foo { E } Foo f; int i; i = f; // OK f = i; // error f = cast(Foo)i; // OK f = 0; // error f = Foo.E; // OK A named enum member cannot declare its own Type. See also: final switch on a named enum. Enum Member ValuesThe value of an EnumMember is given by its AssignExpression if present. If there is no AssignExpression and it is the first EnumMember, its value is converted to EnumBaseType from 0. If there is no AssignExpression and it is not the first EnumMember, it is given the value of the previous EnumMember + 1:
enum E : char { a, b = char.max, c // overflow } static assert(E.a == 0); All EnumMembers are in scope for the AssignExpressions. enum A = 3; enum B { A = A // error, circular reference } enum C { A = B, // A = 4 B = D, // B = 4 C = 3, // C = 3 D // D = 4 } enum E : C { E1 = C.D, E2 // error, C.D is C.max } An empty enum body signifies an opaque enum - the enum members are unknown. enum X; // opaque enum writeln(X.init); // error: enum X is opaque and has no default initializer Enum PropertiesEnum properties only exist for named enums.
For example: enum X { A = 3, B = 1, C = 4, D, E = 2 } X.init // is X.A X.min // is X.B X.max // is X.D X.sizeof // is same as int.sizeof The EnumBaseType of named enums must support comparison in order to compute the .max and .min properties. Enum Copying and AssignmentA named enum type never has a copy constructor, postblit, or identity assignment overload, even if one is defined by its EnumBaseType. When copying a named enum value whose base type is a struct with a copy constructor, the copy constructor is not called: struct S { this(ref S rhs) { assert(0); } } enum E : S { A = S.init } void main() { E e1; E e2 = e1; // ok - copy constructor not called } When copying a named enum value whose base type is a struct with a postblit, the postblit is not called: struct S { this(this) { assert(0); } } enum E : S { A = S.init } void main() { E e1; E e2 = e1; // ok - postblit not called } When assigning a named enum value to another object of the same type, if the base type of those values is a struct with an identity assignment overload, the identity assignment overload is not called: struct S { void opAssign(S rhs) { assert(0); } } enum E : S { A = S.init } void main() { E e1, e2; e2 = e1; // ok - opAssign not called } Anonymous EnumsIf the enum Identifier is not present, then the enum is an anonymous enum, and the EnumMembers are declared in the scope the EnumDeclaration appears in. No new type is created. The EnumMembers can have different types. Those types are given by the first of:
enum { A, B, C } // anonymous enum Defines the constants A = 0, B = 1, C = 2, all of type int. Enums must have at least one member. The value of an EnumMember is given by its AssignExpression if present. If there is no AssignExpression and it is the first EnumMember, its value is the .init property of the EnumMember's type. If there is no AssignExpression and it is not the first EnumMember, it is given the value of the previous EnumMember + 1:
All EnumMembers are in scope for the AssignExpressions. enum { A, B = 5 + 7, C, D = 8 + C, E }
Sets A = 0, B = 12, C = 13, D = 21, and E = 22, all of type int. enum : long { A = 3, B } Sets A = 3 and B = 4, both of type long. enum : string { A = "hello", B = "betty", C // error, cannot add 1 to "betty" } enum { A = 1.2f, // A is 1.2f of type float B, // B is 2.2f of type float int C = 3, // C is 3 of type int D // D is 4 of type int } Single Member SyntaxIf there is only one member of an anonymous enum, the { } can be omitted. Gramatically, this is a form of VarDeclarations. enum i = 4; // i is 4 of type int enum long l = 3; // l is 3 of type long This is also known as a manifest constant. Manifest ConstantsEnum members are manifest constants, which exist only at compile-time. Manifest constants are not lvalues, meaning their address cannot be taken. They exist only in the memory of the compiler. enum size = __traits(classInstanceSize, Foo); // evaluated at compile-time The initializer for a manifest constant is evaluated using compile-time function evaluation. template Foo(T) { // Not bad, but the 'size' variable will be located in the executable. const size_t size = T.sizeof; // evaluated at compile-time // ... use of 'size' at compile-time ... } template Bar(T) { // Better, the manifest constant has no runtime location in the executable. enum size_t size = T.sizeof; // evaluated at compile-time // ... use of 'size' at compile time ... // Taking the address of Foo!T.size also causes it to go into the exe file. auto p = &Foo!T.size; } Copyright © 1999-2026 by the D Language Foundation | Page generated by
Ddoc on Mon Nov 9 05:59:19 2026
| ||||||||
| You are visitor 01402503 — GeezerVison does not store the pages you look up. Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required. |