Bug 6114 – immutable class variable not properly initialized when the constructor initializing it is non-shared

Status
RESOLVED
Resolution
DUPLICATE
Severity
normal
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2011-06-05T23:31:00Z
Last change time
2017-07-07T14:09:23Z
Assigned to
nobody
Creator
issues.dlang

Comments

Comment #0 by issues.dlang — 2011-06-05T23:31:52Z
This is related to bug# 6113. If you go into std.datetime and change the static constructors which initialize UTC._utc or LocalTime._localTime (search for "_utc =" or "_localTime =" - minus the quotes - to find them quickly), then this code will fail: import std.datetime; shared static this() { assert(UTC() !is null); assert(LocalTime() !is null); } void main() {} As long as those static constructors are shared, then this code is fine. But if they're not shared, then the assertions fail. I believe that this is related to bug# 4923 and the fact that immutable global variables and immutable static variables are implicitly shared. I really think that the language should be altered such that it be an error to attempt to initialize an immutable global variable or immutable static variable in a non-shared constructor. Since, they're implicitly shared, it doesn't make sense to initialize them in a thread-local manner anyway. And it's obviously causing problems as-is.
Comment #1 by braddr — 2011-06-06T00:21:37Z
While you've framed this as related to immutable (and I agree with your assessment), there's a broader problem of the definition of order of initialization. For the main thread, is it one or two passes?
Comment #2 by schveiguy — 2011-06-08T10:41:02Z
I agree with Jonathan, immutables should not be assignable in non-shared ctors. The runtime works like this: 1. program startup 2. run all shared static ctors 3. run all thread-local static ctors 4. run application 4a. on thread creation, run all thread-local static ctors 4b. on thread destruction, run all thread-local static dtors 5. run all thread-local static dtors 6. run all shared static dtors. 7. end program So everything is unraveled the same way it was, um... raveled :) I think since immutable means 'store globally', it should be only assignable from a shared ctor. Otherwise, you run into issues.
Comment #3 by dlang-bugzilla — 2017-07-05T16:30:03Z
Jonathan, if this is still an issue, could you please post a complete self-contained minimal example?
Comment #4 by issues.dlang — 2017-07-05T17:14:59Z
Really, the larger issue is this one bug# 4923, and maybe this should be closed given that this is really just another manifestation of that, though if I can fix the example for this so that it's self-contained, it's a different sort of example for why immutable globals need to be initialized in shared, static constructors rather than thread-local ones.
Comment #5 by issues.dlang — 2017-07-05T17:20:53Z
Okay, self-contained example: bug.d -------- class C { } immutable C theC; static this() { theC = new immutable C; } -------- test.d -------- import bug; shared static this() { assert(theC !is null); } void main() { } -------- The assertion fails, but if you make the static constructor in bug.d shared, then it doesn't.
Comment #6 by schveiguy — 2017-07-06T19:12:15Z
The example isn't exactly pointing out the error. There are 2 problems here, one is an expectation that a non-shared static ctor might run before the shared one (it doesn't, the order is clearly defined). That's not really a bug. The second is that immutable (shared) data is changing from one thread to the next. I think this should be closed as a dup of 4923. *** This issue has been marked as a duplicate of issue 4923 ***
Comment #7 by dlang-bugzilla — 2017-07-07T06:45:59Z
Thanks!
Comment #8 by issues.dlang — 2017-07-07T14:09:23Z
(In reply to Steven Schveighoffer from comment #6) > The example isn't exactly pointing out the error. > > There are 2 problems here, one is an expectation that a non-shared static > ctor might run before the shared one (it doesn't, the order is clearly > defined). That's not really a bug. > > The second is that immutable (shared) data is changing from one thread to > the next. Really. what this shows is a side effect of the fact that it's currently possible to instantiate an object that's treated as shared in a non-shared, static constructor. It's the fact that the compiler let's you initialize non-local immutable variables in a non-shared, static constructor that's the bug. And once that's fixed, this problem goes away. > I think this should be closed as a dup of 4923. They're different symptoms of the same bug. So, I have no problem with that.