enum

Jonathan M Davis jmdavisProg at gmx.com
Sun Apr 13 06:37:07 PDT 2014


On Saturday, April 12, 2014 12:43:32 Andrei Alexandrescu wrote:
> On 4/12/14, 5:59 AM, Jonathan M Davis wrote:
> > If the enum
> > doesn't enumerate all of the values, then you're clearly going to be using
> > other values with it, meaning that any restrictions on setting a variable
> > to those other values is going to be a problem (as is currently the case
> > with enums - assignment and initialization are protected against
> > non-enumerated values). You'd just end up with a enum type which is
> > effectively an alias for the enum's base type except that assigning it
> > non-enumerated values requires casting, and you can overload a function
> > on the enumerated values vs the non- enumerated ones (or at  least,
> > non-enumerated ones which aren't cast to the enum type) by overloading a
> > function on the enum type and its base type - which would be highly
> > bug-prone IMHO.
> 
> Sorry, your speculations are mistaken. The pattern works well and we've
> been using it repeatedly and with good results since C++ introduced
> "enum class".

I would have expected that all of the required casting would be annoying and 
that overloading between the enum and its base type would be error-prone, 
because all you have to do is forget to cast when passing a literal, and you 
end up with the wrong overload being called. But I guess if you view casting 
to the enum type like a constructor, then it makes sense, and apparently, it's 
working for you.

Regardless, I'd never use an enum to partially enumerate values for a type, 
because I think that that violates the very concept of what an enumeration is. 
And I expect that enums get used so frequently in other ways primarily due to 
the fact that C's enums are so weakly typed. I'd use a struct for any case 
where I wanted a new type which didn't have a full enumeration of its values, 
and any constants would probably just be static variables or manifest 
constants on the struct.

So, I'm not at all interested in having D's enum not fully protect against 
having a variable of that enum type end up becoming a non-enumerated value, 
and I don't at all value the ability to have enums which aren't intended to 
enumerate all of their values. But clearly, not everyone agrees on that.

So, if we add final enum, and it properly protects against any operation on a 
variable of that enum type ever becoming a non-enumerated value without a 
cast, and it works with final switch, then great. I won't like what non-final 
enums do, and I'll never use them, but at least then we can have non-buggy 
behavior for enums which are intended to enumerate all of their values.

As it stands, I think that C++'s enum class are better than D's enums, because 
they actually protect against any operations (other than casts) giving the 
enum a non-enumerated value, and Ds enums don't  - though enum classes 
arguably go a bit far, because they don't provide implicit conversions to 
their base type, and you have to overload any operators on the type that you 
want to use. But I'd still rather have that than have to worry about enum 
variables becoming non-enumerated values like we currently have to worry about 
in D - and features like final switch just make it that much worse when an 
enum variable ends up with a non-enumerated value.

- Jonathan M Davis


More information about the Digitalmars-d mailing list