D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 4923 - immutable module variables are modifiable in non-shared module constructors
Summary: immutable module variables are modifiable in non-shared module constructors
Status: RESOLVED FIXED
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D2
Hardware: All All
: P2 normal
Assignee: yebblies
URL:
Keywords: accepts-invalid, pull
: 6114 (view as issue list)
Depends on:
Blocks:
 
Reported: 2010-09-23 12:05 UTC by Kasumi Hanazuki
Modified: 2019-08-12 15:00 UTC (History)
5 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description Kasumi Hanazuki 2010-09-23 12:05:20 UTC
DMD v2.049 on Windows

immutable module variables, whose instances are thread-global, are modifiable in thread-local module constructors (static this).

Following example prints different numbers on each iteration.

----

import core.thread, std.random, std.stdio;

immutable int x;

static this() {
  x = unpredictableSeed;
}

void main() {
  for(;;) {
    (new Thread({ })).start;
    Thread.sleep(1_000_000_0);
    writeln(x);
  }
}
Comment 1 nfxjfg 2010-09-23 16:04:20 UTC
Isn't this by design?
Immutable variables are per-thread, and normal module constructors are used to initialize per-thread data.
You need a way to initialize immutable variables.
Comment 2 Kasumi Hanazuki 2010-09-23 18:25:30 UTC
I have no idea whether the spec states immutable module variables to be allocated per thread or not,
but currently DMD places them as shared and there seems no way to store them in TLS.
Comment 3 Jonathan M Davis 2011-01-04 00:26:06 UTC
immutable variables are implicitly shared. That's part of the point of immutable after all. And given that fact, allowing the initializing of immutable variables in non-shared static constructors is definitely a bug. If we decided that immutable variables were _not_ implicitly shared and made it so that they weren't, then that would fix the problem, but that would on some level defeat the purpose of immutable. So, if we are going to have immutable variables be implicitly shared, then I propose that we disallow the initializing of immutable variables with global scope in non-shared static constructors. That is, all global variables and static variables which are immutable _must_ be initialized in shared static constructors. The non-static local variables would be okay (and I'm not sure that those actually end up being implicitly shared anyway), since they'd be re-created on each function call, but any immutable variable which could be initialized in a static constructor would have to be initialized in a shared static constructor. I don't really see any other viable way to fix this bug if we're going to continue to have immutable variables be implicitly shared.
Comment 5 github-bugzilla 2013-06-30 15:58:06 UTC
Commit pushed to master at https://github.com/D-Programming-Language/phobos

https://github.com/D-Programming-Language/phobos/commit/f5ed82d638b373efb6c2f0c77d64259df9472964
Merge pull request #1376 from yebblies/issue4923

initialize first thread's message box in a normal static ctor, to work around requirement that thread-local variables cannot be set from a shared static constructor.
Comment 6 Jonathan M Davis 2017-07-05 17:12:08 UTC
An updated example, since Thread.sleep now requires that its argument be a core.time.Duration:

import core.thread, std.random, std.stdio;

immutable int x;

static this() {
  x = unpredictableSeed;
}

void main() {
  for(;;) {
    (new Thread({ })).start;
    Thread.sleep(seconds(1));
    writeln(x);
  }
}
Comment 7 Steven Schveighoffer 2017-07-06 19:12:15 UTC
*** Issue 6114 has been marked as a duplicate of this issue. ***
Comment 8 Dlang Bot 2019-05-09 09:47:11 UTC
@Geod24 created dlang/dmd pull request #9754 "Fix issue 4923: Deprecate modifying immutable variable from `static this`" fixing this issue:

- Fix issue 4923: Deprecate modifying immutable variable from `static this`

https://github.com/dlang/dmd/pull/9754
Comment 9 Dlang Bot 2019-05-10 15:25:25 UTC
dlang/dmd pull request #9754 "Fix issue 4923: Deprecate modifying immutable variable from `static this`" was merged into master:

- 7c4ccb75c9aee7dfaac66c65fe0fb11d29bca8b9 by Geod24:
  Fix issue 4923: Deprecate modifying immutable variable from `static this`

https://github.com/dlang/dmd/pull/9754