Stop using the enum as a manifest constant.
Steven Schveighoffer
schveiguy at gmail.com
Mon Jun 7 13:02:24 UTC 2021
On 6/6/21 11:05 AM, Mathias LANG wrote:
> 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.
Yeah, I can get it to work if I use an array literal of characters:
```d
enum char[] WAT = [42, 42, 42];
// or
char[] foo() @safe { return [42, 42, 42]; }
enum WAT = foo();
```
but if you use .dup on it, then it treats it like a string literal, e.g.
instead of allocating a new array, it points at the same array
(apparently in the RO segment)
This doesn't happen with an integer array (it's always reallocated on
every call).
Seems like this behavior started with 2.066.
-Steve
More information about the Digitalmars-d
mailing list