[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 im 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