[Date Prev][Date Next][Thread Prev][Thread Next][Author Index][Date Index][Thread Index]

Re: Initialization in X++



Please note that I'm posting the following to invite comments, mainly
on the semantics and any roadblocks, not proposing to immediately do it.

> From eric@son-of-blob Mon Apr 16 17:01:09 1990
> 
> With the introduction of the initTime hook in smalltalk, we have once
> again found a situation where C++'s static initialization and its random
> order is not good enough.  Some time ago, Markm proposed a mechanism to
> have a list of functions to perform at initialization, but after the static
> stuff.  With this new round, I've gone and implemented such a creature.
> Note, however, that presently I don't have a hook to specify the order of
> execution of these initializers.  What is guaranteed is that, if used as
> indicated below, they will all execute after static initialization is
> complete.

This got me thinking about how to specify order.  The obvious approach
would be to say something like:

 	INIT_AT(initGeneration, initName, { code });

where initGeneration is an integer specifying in which of several sets
of initializations to include initializing initName.

Unfortunately, this still leaves initialization order specifiation as
a problem requiring global knowlege, and inviting hairy global bugs.

A little thought led through schemes specifying order in terms of
relationships to previously-specified initializations ("Do me
before/after/same-time-as him.") to the following realization:

  Most (if not all) initialization order constraints arise from
  an ininitializer's own need for prior initialization of one or
  more resources which it uses, and therfore IS ALLOWED TO KNOW
  ABOUT LOCALLY.

I.e., Foo() might need to happen after Bar() and Baz() (which Foo()
knows), but Baz() might need to happen after MemAlloc(), (which Baz()
knows but Foo() does not).

Furthermore:

  The initialization of the required resource need not take place
  until immediately before its first use.

Therefore, it might be possible to write a macro AFTER(initName) that:

 - Checks whether the initName resource is initialized, and if not:
    - Forces its immediate initialization, and
    - Prevents later reinitialization by the normal initialization process.

Which (in c++) would be used like this:

Foo(...)		// Constructor called to init the Foo resource
{
	...
	AFTER(Bar);
	(first use in Foo() of Bar resource)
	...
	AFTER(Baz);
	(first use in Foo() of Baz resource)
	...
}

The initializers could then be executed in any order by the underlying
c++ or smalltalk initialization process, and they would impose any
necessary constraints themselves.

Unanswered questions and possible downsides:

 - Can initialization of such a resource be detected, both for the
   necessary test in AFTER() and so the normal initialization process
   can avoid multiple-initialization of resources?

 - Are the hooks available for forcing initialization?

 - This might require support-library internals-hacking or
   internals-knowlege, locking us more firmly to cfront2.0-based
   C++ platforms.

 - (Putting the initialization-forcing code in the routines that
   manipulate the resources, rather than their callers, would hide
   knowlege even more elegantly and further enhance reliability,
   but it would also impose overhead on run-time use of the resources,
   wouldn't work for virtual member functions, etc.  Flavoring the
   routines (init-time vs run-time) could eliminate run-time overhead,
   but that puts the knowlege that initialization is needed back into
   the callers.)

	Whaddya think?
	michael