Order of initialization

# Michael O'Brien (17 years ago)

I'm unsure how the class level initialization code should run:

Consider:

class Circle extends Shape { print("Circle") } class Shape { print("Shape") }

The RI and ASC currently bomb on this due to the forward class
reference, however, my understanding is that this is perfectly legal.

Now should the Circle initialization code run first because it is
first in the file, or should Shape run first because it is a base class.

Should we see

Circle Shape

or Shape Circle

Michael

# Jeff Dyer (17 years ago)

On 4/18/08 4:52 PM, Michael O'Brien wrote:

I'm unsure how the class level initialization code should run:

Consider:

class Circle extends Shape { print("Circle") } class Shape { print("Shape") }

The RI and ASC currently bomb on this due to the forward class reference, however, my understanding is that this is perfectly legal.

Now should the Circle initialization code run first because it is first in the file, or should Shape run first because it is a base class.

Should we see

Circle Shape

or Shape Circle

Circle Shape

[note that static initialization code must now be put in 'static {...}' blocks]

Class initialization is still an area of open investigation, but here is how I think it should work:

1/classes initialize in the order that they appear. Static fields get initialized in that order too. We want to avoid subtle changes in meaning due to implicit reordering of classes. We leave it to the programmer to define the correct order of initialization.

2/forward type references to types defined in the current compilation unit are allowed. As you pointed out, this is more relaxed than AS3 and the current RI and allows more programs to load successfully.

3/class instances can be created before the class statics have been initialized. Currently class static can be read before they are initialized and provide the default value of the storage type. I can imagine adding read barriers to static vars to ensure that they are initialized before use. We could disallow the instantiation of class instances before its statics are initalized, but that would seem to make completely safe programs illegal while not providing any more safety than a read barrier on static properties.

Consider this case:

class B extends A { static var a static { print ("static B") a = new A } function B () { print ("new B") } }

class A { static var b static { print ("static A") b = new B } function A () { print ("new A") } }

prints:

static B new A static A new B new A [call to super constructor]

Thoughts?

# Michael O'Brien (17 years ago)

Jeff, comments below:

Consider:

class Circle extends Shape { print("Circle") } class Shape { print("Shape") }

Should we see

Circle Shape

[note that static initialization code must now be put in 'static
{...}' blocks]

Class initialization is still an area of open investigation, but
here is how I think it should work:

1/classes initialize in the order that they appear. Static fields get initialized in that order too. We want to avoid subtle changes in
meaning due to implicit reordering of classes. We leave it to the programmer
to define the correct order of initialization.

I would have thought that a slight modification may work better. I'd
propose initialization starting with order in the file and then doing
a recursive descent of base classes, doing the base classes first, and
making sure a class is initialized only once. That way a class static
initializer will always have its static base class members initialized
before it runs. This should be deterministic and not changing from
implementation to implementation.

Just doing class order will allow static initializers to run before
their base classes are initialized. This is problematic. Can you point
out where this model would file?

2/forward type references to types defined in the current
compilation unit are allowed. As you pointed out, this is more relaxed than AS3 and the current RI and allows more programs to load successfully.

Good. What about across compilation units, that has to be allowed
also. Now that packages are gone and without explicit importing, you
must allow cross file references.

3/class instances can be created before the class statics have been initialized. Currently class static can be read before they are
initialized and provide the default value of the storage type. I can imagine
adding read barriers to static vars to ensure that they are initialized before
use. We could disallow the instantiation of class instances before its
statics are initalized, but that would seem to make completely safe programs
illegal while not providing any more safety than a read barrier on static properties.

Consider this case:

class B extends A { static var a static { print ("static B") a = new A } function B () { print ("new B") } }

class A { static var b static { print ("static A") b = new B } function A () { print ("new A") } }

prints:

static B new A static A new B new A [call to super constructor]

Thoughts?

So in essence, the problem is creating an instance of a class while it
is being statically initialized. In general, I'd suggest throwing a
reference error if an instance of a class is attempted while its
static initializer is still executing, as it would usually be a
program design flaw. Better to move such code into a static method to
run after class initialization.