order of static constructor execution

Michel Fortin michel.fortin at michelf.com
Fri Mar 12 06:05:25 PST 2010


On 2010-03-11 21:42:47 -0500, Walter Bright <newshound1 at digitalmars.com> said:

> Currently, it is performed as a strictly "depth-first" traversal of the 
> graph defined by the import statements. As we've been discussing here, 
> this works great until one has circular imports, meaning the 
> depth-first graph has a loop in it.
> 
> The current behavior on detecting a loop is to quit with an error message.
> 
> The problems are:
> 
> 1. The cycles are not easily gotten rid of when they are the result of 
> template mixins.
> 
> 2. Trying to analyze the static constructors to see what the 
> dependencies actually are is fraught with unsolvable problems.
> 
> 
> So, I propose the following:
> 
> 1. Attempt the depth-first traversal of the static constructors.
> 
> 2. If a loop is detected, rather than issuing an error message, simply 
> arbitrarily pick one order and continue constructing.
> 
> 
> The mitigating rationale is that modules that import each other are 
> presumably written by the same person or team, and so that person is in 
> the best place to explicitly control dependencies themselves.
> 
> 
> I'm not happy with this solution, but it seems to be the best 
> compromise I can come up with.
> 
> What do you think?

I think it'd be better if it was explicit. Perhaps better would be an 
opt-in using an attribute on the static constructor. For instance:

module a;
import b;

int a;

static this() {
	a = b;
}


module b;
import a;

int b;

@cyclehead static this() {
	b = 10;
}


Here, module 'a' initialization depends on 'b'. Module 'b' 
initialization does not depend on a or anything, so you can make it 
@cyclehead. @cyclehead means that this module, when part of a cycle, 
can be initialized before the others. If all 'static this' in a module 
are @cyclehead, then the module gets the cyclehead flag and is 
initialized first in the cycle.

This is better than just picking one module at random to break the 
cycle. If no module have the cyclehead flag, then having a cycle is an 
error. The programmer will have to consciously choose one module to 
break the cycle.

Most mixins static constructors will probably have to be @cyclehead.

-- 
Michel Fortin
michel.fortin at michelf.com
http://michelf.com/




More information about the Digitalmars-d mailing list