Stop using the enum as a manifest constant.

Mathias LANG geod24 at gmail.com
Sun Jun 6 15:05:47 UTC 2021


On Sunday, 6 June 2021 at 14:05:54 UTC, Jack Applegame wrote:
> On Sunday, 6 June 2021 at 13:21:35 UTC, Mathias LANG wrote:
>> It *might*, e.g. the following:
>> ```D
>> enum DEFAULT = foo();
>> char[] foo () { return null; }
>> void bar (char[] arg = DEFAULT);
>> ```
>
> Mutable enum??? WAT?
> It's absolutely unacceptable.
>
> ```d
> char[] foo() @safe { return "hello".dup; }
> enum WAT = foo();
> void main() @safe {
>     WAT[0] = 'w';
>     writeln(WAT);
> }
> ```
> ```shell
> Error: program killed by signal 11
> ```

This is... interesting. I did a bit of digging in memory and the 
code was actually using `int[]` (or at least, not `char[]`), so 
it was something like this:
```D
import std.stdio;
int[] foo() @safe { return [42, 42, 42]; }
enum WAT = foo();
void main() @safe {
     bar();
}
void bar(int[] data = WAT) @safe
{
     data[0] = 84;
     writeln(data);
     writeln(WAT);
}
```

The above works as expected (at least, as *I* would expect). 
However, change the type to `char[]` and it SEGV. That's probably 
because string literals are special and the compiler makes some 
(bad) assumptions.

However, the compiler shouldn't allow you to use an enum as an 
lvalue.  It used to be able to recognize this, but it broke at 
some point after v2.080.0.


More information about the Digitalmars-d mailing list