Tim Matthews wrote:
Walter Bright wrote:
It's unreliable because how do you specify the load order? And how
does the user relate that to the source semantics?
grauzone suggested this earlier:
static this {} //full dependencies (all import statements)
static this : a, b {} //only dependent from module a and b
static this : void {} //no dependencies at all
Such annotations tend to get seriously out of date and wrong as code
evolves. For example, if A and B import each other:
-----------------------------
--- A ---
import B;
int foo() { ... }
static this()
{
...
}
--- B ---
import A;
import C;
int x;
static this : C()
{
x = A.foo();
}
-------------------------------
Now, this may work just fine, until module A gets updated at some point
in the future to depend on its static constructor. Then, B.x will get
some unpredictable value, depending on the order of initialization.
So, in general, annotations in one module that specify what happens in
another module are bad maintenance bugs waiting to happen.
The solution is relatively robust and straightforward. Create a third
module, AB. Module A and module B both import AB. Put the static
constructors for both A and B in module AB. The order of initialization
problem is robustly solved, and all the interdependencies of
initialization of A and B are explicitly laid out in AB.