Enum alias members: yay or nay?

Andrej Mitrovic andrej.mitrovich at gmail.com
Sat Sep 7 17:08:54 PDT 2013


I've recently ran into a bug that was very hard to track down for me.
I've had a good set of unittests, but I kept getting the wrong results
out of my functions, which was very bizarre.

To boil it down, when you introduce a member in an enum which
initializes itself to another member of that enum, the next member
after it will be initialized to + 1 of the previous member. So:

enum E
{
    a,
    b = a,
    c
}

Here, a equals 0, b equals 0 as well, and c equals b + 1, so it's 1.
There's nothing problematic here.

The real problem appears when you need to make sure each member is
unique, except for any members which are either convenience members or
are deprecated members (there's no "deprecated" member feature
yet[2]).

Here's an example:

enum MouseAction
{
    ///
    press,

    ///
    release,

    /** Convenience - equal to $(D press). */
    click = press,

    ///
    double_click,
}

Notice how introducing the convenience member has re-set the enum
initializer counter, meaning double_click will be equal to (click +
1), which is really (press + 1), which becomes (1). But (1) is also
the intializer for "release", so by mistake I made "double_click"
equal "release", and hence my bug.

So to work around this, I thought about introducing an alias feature to enums:

enum MouseAction
{
    press,

    release,

    alias click = press,  // does not reset the counter!

    double_click,  // equals release + 1
}

The alias member would not re-set the counter and instead the next
non-alias member would initialize itself to the previous non-alias
member + 1.

This would also lend itself well with the "deprecated" keyword, where
we could add deprecated aliases for old enum members when we want to
rename the members. For example, if you want to rename a Phobos enum
you can currently do :

enum SpanMode
{
    shallow,
    deep,
    depth = deep;  /// $(RED Deprecated, please use .deep)
    breadth,
}

With the enhancements Issue 9395[2] and Issue 10965[1] we could write
the above as:

enum SpanMode
{
    shallow,
    deep,
    deprecated("Please use .deep") alias depth = deep;
    breadth,
}

Anyway, before I knew it and before any discussion took place, Henning
Pohl already made a pull request[3] implementing the feature! So I had
to go to the newsgroups.

Does the alias member feature pull its weight? Or is it overkill and
we should drop it?

[1] : http://d.puremagic.com/issues/show_bug.cgi?id=10965
[2] : http://d.puremagic.com/issues/show_bug.cgi?id=9395
[3] : https://github.com/D-Programming-Language/dmd/pull/2529


More information about the Digitalmars-d mailing list