Enumeration Type-Safety in D

Jonathan M Davis jmdavisProg at gmx.com
Thu Nov 7 08:04:07 PST 2013


On Thursday, November 07, 2013 14:25:38 Nordlöw wrote:
> What is the state and plans on type-safety of enums in D?
> 
> I expected
> 
> import std.stdio: writeln;
> 
> void main(string args[]) {
>      enum E {x, y, z}
>      E e;
>      writeln(e);
>      e = cast(E)3;
>      writeln(e);
> }
> 
> to fail to compile because of D's otherwise strong static
> type/range checking or at least give an RangeException when run.
> 
> To my surprise, it instead prints
> 
> cast(E)3
> 
> Is this really the preferred default behaviour for the majority
> of use cases?

If you're casting, then I think that it's perfectly reasonable that this sort 
of thing can happen. The problem is when it happens without casting. e.g.

enum E : string { a = "hello", b = "goodbye" }

void main()
{
    E foo = E.a;
    foo ~= " world";
    assert(foo == "hello world");
}

or

enum E : int { a = 1, b = 2 }

void main()
{
    E foo = E.a | E.b;
    assert(foo == 3);
}

IMHO, it should not be legal to construct invalid enums without casting, but 
unfortunately, right now, it very much is. For the most part, you can do 
operations on enums that are completely valid for their base type, and the 
result ends up being the enum type instead of the base type like it should. I 
don't know what the odds are of getting this fixed, but I think that it should 
be.

However, even it were properly enforced that operations done on enum values 
would either be guaranteed to result in a valid enum value or would result in 
the base type instead of the enum type, I'd still expect casting to get around 
that as casting is a blunt instrument which forces the issue. As others have 
pointed out, you should use std.conv.to if you want the conversion to be 
checked for validity.

- Jonathan M Davis


More information about the Digitalmars-d mailing list