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

Reply via email to