Mutable enums

Timon Gehr timon.gehr at gmx.ch
Mon Nov 14 10:37:18 PST 2011


On 11/14/2011 02:13 PM, Steven Schveighoffer wrote:
> On Mon, 14 Nov 2011 03:27:21 -0500, Timon Gehr <timon.gehr at gmx.ch> wrote:
>
>> On 11/14/2011 01:02 AM, bearophile wrote:
>>> Jonathan M Davis:
>>>
>>>>> import std.algorithm;
>>>>> void main() {
>>>>> enum a = [3, 1, 2];
>>>>> enum s = sort(a);
>>>>> assert(equal(a, [3, 1, 2]));
>>>>> assert(equal(s, [1, 2, 3]));
>>>>> }
>>>>
>>>> It's not a bug. Those an manifest constants. They're copy-pasted
>>>> into whatever
>>>> code you used them in. So,
>>>>
>>>> enum a = [3, 1, 2];
>>>> enum s = sort(a);
>>>>
>>>> is equivalent to
>>>>
>>>> enum a = [3, 1, 2];
>>>> enum s = sort([3, 1, 2]);
>>>
>>> You are right, there's no DMD bug here. Yet, it's a bit surprising to
>>> sort in-place a "constant". I have to stop thinking of them as
>>> constants. I don't like this design of enums...
>>
>> It is the right design. Why should enum imply const or immutable? (or
>> inout, for that matter). They are completely orthogonal.
>
> There is definitely some debatable practice here for wherever enum is
> used on an array.
>
> Consider that:
>
> enum a = "hello";
>
> foo(a);
>
> Does not allocate heap memory, even though "hello" is a reference type.
>
> However:
>
> enum a = ['h', 'e', 'l', 'l', 'o'];
>
> foo(a);
>
> Allocates heap memory every time a is *used*. This is counter-intuitive,
> one uses enum to define things using the compiler, not during runtime.
> It's used to invoke CTFE, to avoid heap allocation. It's not a glorified
> #define macro.
>
> The deep issue here is not that enum is used as a manifest constant, but
> rather the fact that enum can map to a *function call* rather than the
> *result* of that function call.
>
> Would you say this should be acceptable?
>
> enum a = malloc(5);
>
> foo(a); // calls malloc(5) and passes the result to foo.
>
> If the [...] form is an acceptable enum, I contend that malloc should be
> acceptable as well.
>

a indeed refers to the result of the evaluation of ['h', 'e', 'l', 'l', 
'o'].

enum a = {return ['h', 'e', 'l', 'l', 'o'];}(); // also allocates on 
every use

But malloc is not CTFE-able, that is why it fails.


> My view is that enum should only be acceptable on data that is
> immutable, or implicitly cast to immutable,

Too restrictive imho.

> and should *never* map to an
> expression that calls a function during runtime.
>

Well, I would not miss that at all.
But being stored as enum should not imply restrictions on type qualifiers.


More information about the Digitalmars-d-learn mailing list