Bug 23375 – enum is not considered global mutable state

Status
NEW
Severity
critical
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2022-09-26T09:42:03Z
Last change time
2024-12-13T19:24:48Z
Keywords
accepts-invalid
Assigned to
No Owner
Creator
Bolpat
Moved to GitHub: dmd#20158 →

Comments

Comment #0 by qs.il.paperinik — 2022-09-26T09:42:03Z
An enum of slice of class can be mutated and it can be mutated even in a `pure` function. Example: class C { string s; this(string a) pure @safe nothrow { s = a; } } enum C[] cs = [ new C("a"), new C("b") ]; void f() pure @safe @nogc nothrow { cs[0].s = "c"; }
Comment #1 by dkorpel — 2022-09-26T09:59:57Z
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.
Comment #2 by qs.il.paperinik — 2022-09-26T12:28:42Z
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]); }
Comment #3 by robert.schadek — 2024-12-13T19:24:48Z
THIS ISSUE HAS BEEN MOVED TO GITHUB https://github.com/dlang/dmd/issues/20158 DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB