static init cycle detection problem

"Øivind" oivind.loe at gmail.com
Thu Sep 20 11:49:32 PDT 2012


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


More information about the Digitalmars-d-learn mailing list