www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - more cyclical confoundedness

reply Ellery Newcomer <ellery-newcomer utulsa.edu> writes:
Hello.

When I have three files test1.d test2.d test3.d as follows:

module test1;
import tango.io.Stdout;
import test3;
static this(){
     Stdout("test1\n");
}


module test2;
import test1;
//no ctor


module test3;
import tango.io.Stdout;
import test2;
static this(){
     Stdout("test3\n");
}


and main.d:

module main;
import tango.io.Stdout;
import test1;
import test2;
import test3;
main(){}
static this(){
     Stdout("main\n");
}


It works dandy, compiling AND running to give me

test3
test1
main

But if I change the import order to begin with

import test3;

it barfs with the cyclic dependency runtime error. All other 
combinations give output same as the first.

Now, what the heck is going on? As near as I can tell these should all 
fail at runtime. Or am I missing something?
Apr 05 2009
parent reply Ellery Newcomer <ellery-newcomer utulsa.edu> writes:
Och, I feel so alone. I'll rephrase the question:

How is a cyclic dependency defined? Is it a cycle formed by imports in 
which two or more of the modules contain static constructors?

The reason I ask is because I'm trying to mechanize finding these cyclic 
dependencies, and my example suggests that the above assumption will 
generate a large proportion of false positives, or else the compiler 
ignores a large proportion of true positives.

Ellery Newcomer wrote:
 Hello.
 
 When I have three files test1.d test2.d test3.d as follows:
 
 module test1;
 import tango.io.Stdout;
 import test3;
 static this(){
     Stdout("test1\n");
 }
 
 
 module test2;
 import test1;
 //no ctor
 
 
 module test3;
 import tango.io.Stdout;
 import test2;
 static this(){
     Stdout("test3\n");
 }
 
 
 and main.d:
 
 module main;
 import tango.io.Stdout;
 import test1;
 import test2;
 import test3;
 main(){}
 static this(){
     Stdout("main\n");
 }
 
 
 It works dandy, compiling AND running to give me
 
 test3
 test1
 main
 
 But if I change the import order to begin with
 
 import test3;
 
 it barfs with the cyclic dependency runtime error. All other 
 combinations give output same as the first.
 
 Now, what the heck is going on? As near as I can tell these should all 
 fail at runtime. Or am I missing something?
Apr 08 2009
parent Jarrett Billingsley <jarrett.billingsley gmail.com> writes:
On Wed, Apr 8, 2009 at 11:14 PM, Ellery Newcomer
<ellery-newcomer utulsa.edu> wrote:
 Och, I feel so alone. I'll rephrase the question:

 How is a cyclic dependency defined? Is it a cycle formed by imports in which
 two or more of the modules contain static constructors?

 The reason I ask is because I'm trying to mechanize finding these cyclic
 dependencies, and my example suggests that the above assumption will
 generate a large proportion of false positives, or else the compiler ignores
 a large proportion of true positives.
Cyclic module initialization dependencies are not detected by the compiler, but instead by the runtime. The reasons for this are somewhat weak (you _might_ have a separately-compiled module whose interface is defined in a .di file that doesn't tell you there's a static ctor.. sounds like a deficiency in .di files to me). Basically the way it works is that it starts with the module that contains main (I think?), then does a depth-first inorder initialization of all modules that it imports. When a module with a static ctor is encountered, it is flagged as "in the process of being initialized", then any modules that it imports are initialized, then its static ctor is run, and then it is flagged as "done being initialized". If a module has no static ctor, it is never marked as "in the process". If, at any time, an attempt is made to initialize a module which is already in the process, an exception is thrown and you get the dreadful "cyclic dependency" runtime error. Your example code confounds me. I don't know why it behaves differently based on import order. Like you, I'd expect for there to be a cyclic initialization in either case.
Apr 08 2009