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.

Reply via email to