enum confusion

Steven Schveighoffer schveiguy at gmail.com
Thu May 12 02:16:38 UTC 2022


On 5/8/22 9:50 PM, Don Allen wrote:

> But ... you knew this was coming ... I find enums and/or their 
> documentation to be a weak spot. As time permits, I'll have more to say 
> about this, but I want to raise an initial issue here for comments.

There are 2 types of enum meaning -- one is like #define, and declares 
there's some value that only exists at compile-time. That's the manifest 
constant.

That is done by using enum kind of as a storage class (like const).

```d
enum x = 5; // x is now a manifest constant of type int.
enum byte y = 5; // y is now a manifest constant of type byte.

writeln(&x); // error, not an lvalue, this is equivalent to:
writeln(&5);
```

The second type of enum meaning is to *declare a type*. This type can be 
an lvalue:

```d
enum Foo {
    bar
}

Foo foo;
writeln(&foo); // ok
```

The symbol Foo now becomes a type, and can be used to denote an integer 
value that has only one value (Foo.bar). Though technically, it can be 
any int value via casting or math operations. You can also specify a 
base type if desired.

Some libraries use this as a crude typedef (with extra manifest constant 
properties).

An anonymous enum is a weird way of declaring a bunch of manifest 
constants, and use the "= last member + 1" feature for declaring them 
(if that's what you want). I don't think many people use them. Yes, I 
see that they are the same thing as manifest constants with one member, 
but I don't ever think of them that way.

You can also declare an enum with an identifier, but without any members 
and becomes a type without a default initializer. Mostly usable as a 
handy UDA tag.

```d
enum dontSerialize;

struct S
{
    @dontSerialize string comment;
}
```

enum is definitely one of the stranger things in D.

-Steve


More information about the Digitalmars-d mailing list