On Thursday, 20 September 2012 at 00:23:33 UTC, Jonathan M Davis
wrote:
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
Thanks for the explination. The trick you talk about has worked
for me before, but now I really need static init of modules that
depend on eachother. Only solution I can think of is to list all
modules in a script and generate d code from this to call init
functions.. Then pass it to dmd along with the other code.
Sad that we can't get this to work like it really should. D is a
very flexible language in many ways, and it seems strange that it
should not allow the stuff I want to do here..
-Øivind