[M3devel] order of module initialization...

Mika Nystrom mika at async.caltech.edu
Tue Apr 24 22:21:25 CEST 2007


Yes, that is the entire rule.  There can definitely be cycles in
the graph; in this case, the rule "if M depends on N and N does not
depend on M" does not apply, as they depend on each other.  The
order of initialization is then implementation-dependent.

Just creating objects of type (circularly) implemented by another
module doesn't present any special problems, unless the correct
functioning of those objects is dependent on module-initialization
code.  And I don't know about your compiler, but mine won't link things
that didn't compile.

I have to admit that the module initialization rule does break a
nice property of Modula-3 programs, which is that you can't normally
break a module by making a change to another module.  If your module
M indirectly depends on module N and furthermore, the correct
functioning of the M-N relationship depends on module N's being
initialized before module M, the addition in module N (in private
implementation code) of a dependency on module M's exported interface
can cause your program to fail.

     Mika


"j k" writes:
>ok. Can there be circularities in the graph?
>Two modules creating objects of types implemented by the other in their 
>module initializer? Or that won't compile? I'll have to try it.
>
>- Jay
>
>
>>From: Mika Nystrom <mika at async.caltech.edu>
>>To: "j k" <jayk123 at hotmail.com>
>>CC: dragisha at m3w.org, m3devel at elegosoft.com
>>Subject: Re: [M3devel] order of module initialization... Date: Fri, 20 Apr 
>>2007 15:15:16 -0700
>>
>>The order in Modula-3 is defined in section 2.5.6 of the language
>>report (page 47 of Systems Programming with Modula-3).
>>
>>The problem described here appears to be that EXPORTS isn't treated
>>the same as IMPORT (which it should be).  There are some other
>>problems I noticed when porting PM3 code to CM3, don't know if they
>>have been fixed.  The "solution" in that case was to IMPORT interfaces
>>in places where they weren't really needed.
>>
>>Obfuscating one's code to avoid taking advantage of the convenience
>>of module initialization seems like a rather severe suggestion...
>>
>>The rule, by the way, is:
>>
>>"If module M depends on module N and N does not depend on M, then
>>N's body will be executed before M's body, where:
>>
>>* A module M 'depends on' a module N if M uses an interface that N
>>exports or if M depends on a module that depends on N.
>>
>>* A module M 'uses' an interface I if M imports or exports I or if
>>M uses an interface that imports I.
>>
>>Except for this constraint, the order of execution is
>>implementation-dependent."
>>
>>      Mika
>>
>>"j k" writes:
>> >Reminds me of C++ globals with constructors.
>> >
>> >The solution is to avoid initialization.
>> >
>> >Do everything "on demand" and hide all state behind functions.
>> >   and then "on demand" needs to be thread safe, so there is a small
>> >bootstrapping problem -- basically the only initialization you should do,
>> >speaking in Win32-ese, is a few calls to InitializeCriticalSection and 
>>maybe
>> >TlsAlloc and maybe HeapAlloc, but nothing "cross module", or more
>> >accurately, nothing "in the same layer", if you have a dependency graph,
>> >only "to a lower layer", which InitializeCritical/TlsAlloc nearly always 
>>are
>> >(unless you are working on ntdll.dll, but even then.. :) ) If you don't 
>>have
>> >a strict layered design, or can't capture what it is and analyze 
>>statically,
>> >again, just restricting yourself to InitializeCriticalSection/TlsAlloc is 
>>an
>> >easy way to be correct.
>> >
>> >And even then, you can often avoid the critical sections via something 
>>like
>> >InterlockedCompareExchangePointer, even implement spin locks for this 
>rare
>> >code. (Hand written spin locks are generally to be avoided since the 
>>kernel
>> >won't know about them and you won't schedule efficiently, whereas with
>> >EnterCriticalSection, if there is contention, the kernel has a hint what 
>>is
>> >going on and can schedule better).
>> >
>> >Don't have any "public global data",  unless, and I don't know if this
>> >applies in Modula-3, unless it is "constant initialized", which I'm not 
>>sure
>> >is well defined in C++ or not. I do believe it is well defined in 
>>C..except
>> >dynamic linking I think screws that up to.
>> >
>> >(pardon the Win32-centricity; I'm sure the principles apply more broadly)
>> >
>> >Ok, in C++ and in Modula-3, there are maybe better answers.
>> >In C++, globals within a source file are guaranteed to be initialized in 
>>the
>> >order they occur in the file.
>> >But the order of files is not defined.
>> >There is a documented trick..potentially very inefficient..that I don't 
>>have
>> >the patience to describe here.. "the iostream counter trick"... this I 
>>don't
>> >think has an analog in Modula-3, but sure.
>> >Stroupstroup's Design and Evolution book documents it.
>> >
>> >- Jay
>> >
>> >
>> >>From: Dragiša Durić <dragisha at m3w.org>
>> >>To: "M3 Developers' Mailing List" <m3devel at elegosoft.com>
>> >>Subject: [M3devel] order of module initialization...
>> >>Date: Fri, 20 Apr 2007 21:36:25 +0200
>> >>
>> >>I remember debugging this first time we tried to migrate to CM3... And
>> >>then we solved it, for current CM3 and current version of our software,
>> >>mentioning some imported module in EXPORTS clause... at the moment, this
>> >>linked these modules in initialization chain  and it worked ok... Right
>> >>now, it does not.
>> >>
>> >>Module XLBuiltin is one imported regularly, and XLModuleUDP (for
>> >>example) both EXPORTS and IMPORTs XLBuiltin. It is linked and starts to
>> >>initialize, but _before_ XLBuiltin... And, fails. Something is NIL @
>> >>wrong moment...
>> >>
>> >>What would be solution for this?
>> >>
>> >>dd
>> >>--
>> >>Dragiša Durić <dragisha at m3w.org>
>> >>
>> >>_______________________________________________
>> >>M3devel mailing list
>> >>M3devel at elegosoft.com
>> >>https://mail.elegosoft.com/cgi-bin/mailman/listinfo/m3devel
>> >
>> >_________________________________________________________________
>> >Download Messenger. Join the i’m Initiative. Help make a difference 
>>today.
>> >http://im.live.com/messenger/im/home/?source=TAGHM_APR07
>> >
>> >_______________________________________________
>> >M3devel mailing list
>> >M3devel at elegosoft.com
>> >https://mail.elegosoft.com/cgi-bin/mailman/listinfo/m3devel
>
>_________________________________________________________________
>Mortgage rates near historic lows. Refinance $200,000 loan for as low as 
>$771/month* 
>https://www2.nextag.com/goto.jsp?product=100000035&url=%2fst.jsp&tm=y&search=m
>ortgage_text_links_88_h27f8&disc=y&vers=689&s=4056&p=5117



More information about the M3devel mailing list