Thread overview
[Issue 23375] enum is not considered global mutable state
Sep 26, 2022
Bolpat
Sep 26, 2022
Dennis
Sep 26, 2022
Bolpat
Oct 04, 2022
ZombineDev
Dec 17, 2022
Iain Buclaw
September 26, 2022
https://issues.dlang.org/show_bug.cgi?id=23375

Bolpat <qs.il.paperinik@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |accepts-invalid
                 CC|                            |qs.il.paperinik@gmail.com

--
September 26, 2022
https://issues.dlang.org/show_bug.cgi?id=23375

Dennis <dkorpel@live.nl> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |dkorpel@live.nl

--- Comment #1 from Dennis <dkorpel@live.nl> ---
I thought it would allocate a new array literal in f(), but it really modifies
global state:

```
class C
{
    string s;
    this(string a) pure @safe nothrow  { s = a; }
    override string toString() {return s;}
}

enum C[] cs = [ new C("a"), new C("b") ];

void f() pure @safe @nogc nothrow
{
    cs[0].s = "c";
}

import std.writeln;
void main()
{
    writeln(cs); // [a, b]
    f();
    writeln(cs); // [c, b]
}
```

I think the could should be accepted without @nogc, and it would modify a copy of the array.

--
September 26, 2022
https://issues.dlang.org/show_bug.cgi?id=23375

--- Comment #2 from Bolpat <qs.il.paperinik@gmail.com> ---
As enum was intended to be a replacement of C’s `#define` constants, the compiler should thoroughly treat `enum` as a named literal; it can support “mutable” indirections, but a lot more has to be taken. By “mutable” I mean typed non-const, not that actual mutation is valid.

An easy way would be to specify that enums are deep-copied at usage site. This might be possible because circular definitions are rejected:

    class C
    {
        C bestie;
        this() { }
        this(C friend) { bestie = friend; }
    }

    enum C me = new C(you);
    enum C you = new C(me); // error
    enum C[] us = [ me, you ];

But you can cheese it:

    enum C[] us = [ new C, new C ];

    shared static this()
    {
        us[0].bestie = us[1];
        us[1].bestie = us[0];
    }

    void main()
    {
        assert(us[0].bestie is us[1]);
        assert(us[1].bestie is us[0]);
        assert(us[0].bestie.bestie is us[0]);
        assert(us[1].bestie.bestie is us[1]);
    }

--
October 04, 2022
https://issues.dlang.org/show_bug.cgi?id=23375

ZombineDev <petar.p.kirov@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |petar.p.kirov@gmail.com

--
December 17, 2022
https://issues.dlang.org/show_bug.cgi?id=23375

Iain Buclaw <ibuclaw@gdcproject.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Priority|P1                          |P2

--