Bug 668 – Use of *.di files breaks the order of static module construction
Status
RESOLVED
Resolution
FIXED
Severity
blocker
Priority
P2
Component
dmd
Product
D
Version
D1 (retired)
Platform
x86
OS
All
Creation time
2006-12-09T10:28:00Z
Last change time
2014-02-15T13:18:57Z
Keywords
wrong-code
Assigned to
bugzilla
Creator
kinaba
Comments
Comment #0 by kinaba — 2006-12-09T10:28:46Z
The spec says that "each module is assumed to depend on any
imported modules being statically constructed first" in module.html.
But when I use *.di interface files, the order seems broken.
Here is an example:
//credit goes to http://pc8.2ch.net/test/read.cgi/tech/1158013550/987
------- lib.d -------
bool initialized;
static this(){ initialized = true; }
------- main.d -------
import lib;
import std.stdio;
void main(){ }
static this(){ writefln("lib.initialized? ", lib.initialized); }
> dmd -c -H lib.d // generating lib.di
> dmd main.d lib.obj
> main
lib.initialized? false // wrong
> del lib.di // deleteing b.di
> dmd main.d lib.obj
> main
lib.initialized? true // correct
Comment #1 by fvbommel — 2006-12-10T04:49:34Z
The likely cause:
-----
urxae@localhost:~/tmp$ cat lib.d
bool initialized;
static this(){ initialized = true; }
urxae@localhost:~/tmp$ dmd -H -c lib.d
urxae@localhost:~/tmp$ cat lib.di
// D import file generated from 'lib.d'
bool initialized;
-----
The static constructor isn't present in the .di so the compiler doesn't see it when compiling main.d.
Confirmed on dmd-0.177/Linux.
Comment #2 by kamm-removethis — 2007-04-25T02:20:13Z
Indeed, when you change lib.di to show the existance of a static constructor:
lib.di
---
// D import file generated from 'lib.d'
bool initialized;
static this();
---
Then it'll work as expected. Confirmed on dmd 1.013.
Comment #3 by sean — 2007-06-18T22:20:19Z
*** Bug 1278 has been marked as a duplicate of this bug. ***
Comment #4 by clayasaurus — 2007-07-03T20:45:18Z
This bug is blocking the Arc v.2 release.
Comment #5 by matti.niemenmaa+dbugzilla — 2007-07-04T01:28:28Z
Raising severity in accordance with clayasaurus's comment.
Comment #6 by braddr — 2007-07-04T01:51:26Z
Strictly speaking, since there's a work around, it's not a blocker. But it's fairly serious so I'll leave it as is.
Comment #7 by clayasaurus — 2007-07-16T23:18:26Z
I'm using a work-around for now and I am going to release Arc v.2, but I still want this bug fixed! :)
Plus, this bug is high-severity for any DSSS installable software, because any DSSS library that uses static ctors will be broken.
Comment #8 by kamm-removethis — 2007-07-23T02:31:35Z
Fixed in DMD 1.019 and 2.003. Thanks Walter!
Comment #9 by sean — 2007-08-06T18:14:58Z
I don't think this issue is completely resolved. The compiler now generates a "static this() {}" in the .di file whenever it seems a static ctor in the module. However, the presence of a complete but empty static ctor seems to convince the compiler that they are available, inlinable and empty. In some instances, this causes errors like:
"filename.di(0): variable SOME_VARIABLE missing initializer in static constructor for const variable"
This is preventing the Tango user library from compiling properly on 1.019 and above for Linux/MacOS.
The solution seems to be generating "static this();" rather than the complete "static this() {}".
Comment #10 by bugzilla — 2007-08-06T20:06:00Z
Please provide a test case.
Comment #11 by sean — 2007-08-06T20:59:52Z
----
// Header.di
class Thread
{
final char[] name();
static const int PRIORITY_MIN;
static const int PRIORITY_MAX;
static Thread getThis();
static this(){}
}
----
// Main.d
private import Header;
class Main
{
void go()
{
char[] threadName = Thread.getThis.name;
}
}
----
C:\> dmd -c -inline -release Main.d
The crucial bit is to have -inline and -release set. Clearing either of these eliminated the problem.