Thread overview
pitfalls of enum
Nov 02, 2013
JR
Nov 14, 2013
Ali Çehreli
Nov 15, 2013
bearophile
Nov 15, 2013
Timothee Cour
November 02, 2013
(TL;DR: when to avoid enum?)

From the dlang.org page on enums;
> Enum declarations are used to define a group of constants. They come in these forms:
> 
> Named enums, which have an EnumTag.
> Anonymous enums, which do not have an EnumTag.
> Manifest constants.

Quoth Dmitry Olshansky in my thread on ctRegex and GC pressure[1]:
> The problem is that ctRegex returns you a pack of datastructures (=arrays).
> Using them with enum makes it behave as if you pasted them as array literals and these do allocate each time.
> 
> TL;DR: use static and/or auto with ctRegex not enum.

1. I see the use and convenience of multi-member enums, be they anonymous or named.
2. I understand it's the preferred way of forcing something to be evaluated at compile-time. The language page does not mention this, but I believe TDPL did?
3. I understand that enums are used to define the value of eponymous template instantiations. (But my snowflake self finds it an unintuitive and ad-hoc way of declaration.)
4. I gather that you should think of enum contents as being copy/pasted to wherever they are used.
5. I understand there's a hidden gotcha with (4) and types that allocate.
6. I understand that, given a string, instantiating any number of other string variables with the value of the first will simply alias them to the same immutable char array. (string abc = "def"; string ghi = abc;)

But in Andrei's thread on tristates[2] he lists this code excerpt:
> struct Tristate
> {
>     private static Tristate make(ubyte b)
>     {
>         Tristate r = void;
>         r.value = b;
>         return r;
>     }
> 
>     enum no = make(0), yes = make(1), unknown = make(4);  // <---

Is it okay to use enum there? If so, is it because (whatwith being a struct) it's not on the heap? What if it were a class? A string? A string instantiated with the value of another string, which would normally simply create an alias?

When is an enum *better* than a normal (static const/immutable) constant?


[1]: http://forum.dlang.org/post/l2456h$18jk$1@digitalmars.com
[2]: http://forum.dlang.org/post/l4gnrc$2glg$1@digitalmars.com


TFMIU. ;>
November 14, 2013
On 11/02/2013 02:14 PM, JR wrote:

> But in Andrei's thread on tristates[2] he lists this code excerpt:
>> struct Tristate
>> {
>>     private static Tristate make(ubyte b)
>>     {
>>         Tristate r = void;
>>         r.value = b;
>>         return r;
>>     }
>>
>>     enum no = make(0), yes = make(1), unknown = make(4);  // <---
>
> Is it okay to use enum there? If so, is it because (whatwith being a
> struct) it's not on the heap?

I think it is more like because its value is known at compile time. If Tristate were a class, then the class variable r would not have any class object that it pointed to.

> What if it were a class?

I tried changing struct to class:

class Tristate
{
    ubyte value;

    private static Tristate make(ubyte b)
    {
        Tristate r = new Tristate();
        r.value = b;
        return r;
    }

    enum no = make(0), yes = make(1), unknown = make(4);
}

Error: variable deneme.Tristate.no : Unable to initialize enum with class or pointer to struct. Use static const variable instead.

So, class can't work.

> A string?

That would be ok. A compile-time string is known to the compiler and can appear in the program binary to be referenced from multiple places.

> A
> string instantiated with the value of another string, which would
> normally simply create an alias?

Would work.

> When is an enum *better* than a normal (static const/immutable) constant?

Good question. :)

Ali

November 15, 2013
Ali Çehreli:

> > When is an enum *better* than a normal (static
> const/immutable) constant?
>
> Good question. :)

When you can or want to compute something at compile-time, when you need values to feed to templates, etc.

Bye,
bearophile
November 15, 2013
On Thu, Nov 14, 2013 at 5:02 PM, bearophile <bearophileHUGS@lycos.com>wrote:

> Ali Çehreli:
>
>
>  > When is an enum *better* than a normal (static
>> const/immutable) constant?
>>
>> Good question. :)
>>
>
> When you can or want to compute something at compile-time, when you need values to feed to templates, etc.
>
>
but you can *can* do that with static const /const/immutable variables too:

auto fun2(int a)(int b){...}
immutable a=fun(2);//static const /const/immutable/enum
auto b=fun2!a(3);