On 2011-03-22 05:16:31 -0400, Max Samukha <m...@spam.box> said:

----
module foo_helper;

private extern(C) foo_static_ctor();
static this()
{
     foo_static_ctor();
}

-----

module foo;
import foo_helper;

private Object global;
private extern(C) void foo_static_ctor()
{
     global = new Object;
}
----

Note that "global" is guaranteed to have been initialized when accessed from static constructors in modules that import "a".

I don't know why people keep repeating that falacy. This statement is true only as long as there are no circular dependencies. It should read: "'global' is guarentied to have been initialized when access from static constructors in module that import 'a' _and_ which are not imported by 'a', directly or indirectly."

Because once you introduce a circular dependency, you get this:

----
module foo_helper;

private extern(C) foo_static_ctor();
static this() { foo_static_ctor(); }
-----
module foo;
import foo_helper;
import bar;

private Object global;
private extern(C) void foo_static_ctor()
{
    global = new Object;
    bar.testGlobal();
}
public void testGlobal()
{
    assert(global);
}
----
module bar_helper;

private extern(C) bar_static_ctor();
static this() { bar_static_ctor(); }
-----
module bar;
import bar_helper;
import foo;

private Object global;
private extern(C) void bar_static_ctor()
{
    global = new Object;
    foo.testGlobal();
}
public void testGlobal()
{
    assert(global);
}
----

Note how foo_static_ctor() and bar_static_ctor() each calls a function that needs the global variable of the other module to be initialized. It should be obvious that it can't work. If you doubt me, try it.


Being able to instruct the compiler to do this implicitly (so we could put static ctors in templates, for example) would probably solve most of static ctor problems.

It'd have the exact same effect as adding a pragma to bypass the check for circular dependencies, while making things more complicated.


--
Michel Fortin
michel.for...@michelf.com
http://michelf.com/

Reply via email to