static init cycle detection problem

Jonathan M Davis jmdavisProg at gmx.com
Wed Sep 19 17:24:26 PDT 2012


On Wednesday, September 19, 2012 22:25:46 Øivind wrote:
> I am struggeling to get around the cycle detection kicking in
> when I have static init in modules that depend on eachother.
> 
> I have seen some threads on 'fixes' for this, e.g. adding a
> @standalone property to the module or similar. Has there been any
> progress on this?

The solution is to do something like what std.stdio does. Instead of having a 
static constructor, it has an extern(C) function which does the same, and then 
it has std/stdiobase.d which has a static constructor which calls that 
extern(C) function in std.stdio. As long as you don't actually have any inter-
dependencies, you can make it work.

Walter has refused suggestions which involve telling the compiler that there 
isn't actually dependency (via an attribute or whatnot) on the grounds that 
you're throwing away the compiler's checks, and it's too easy to screw up. In 
general, you can refactor things so that you don't have the circular 
dependency anymore, and if you can't, and the static constructors aren't 
actually forming a circular dependency, then you can pull the same trick that 
std.stdio does.

> If not would it be possible in e.g. main() to get a list of all
> compiled-in modules, and then iterate over them and call an init
> function where it exists? As long as there is a way to list the
> name of the modules at compile-time, this should be pretty easy..?

It will never be possible to determine the full list of modules at compile 
time due to C's linking model. For instance, you could link together modules 
which were built years apart. There's no way that they could know about each 
other. And since you could be using .di files, and the circular dependencies 
could actually be really indirect, the compiler can't possibly have all of the 
information that it needs to determine circular dependencies. A linker could 
do it but not as long as we use standard, C linkers. And that's not going to 
change.

So, the situation sucks, but there _are_ workarounds. The main one of course 
is to simply limit how much your modules import each other so that the few 
places that you need static constructors don't import each other even 
indirectly, but regardless, it can be worked around as long there isn't a true
circular dependency.

- Jonathan M Davis


More information about the Digitalmars-d-learn mailing list