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