Gang: I now understand a bit more about initialization of static variables -- more accurately, about execution of top-level code -- and while it's not earth-shattering, I thought I'd pass it along. It may avoid some astonishment. The rules are simple, but are different than I thought: -- top level forms INSIDE a class definition are executed every time an instance of that class is created. -- top level forms OUTSIDE of a class definition are executed once when the file loads. To see the implication on initializing a static variable, consider the following: ===== file: t1.ck public class Statix { // UNO is set with to new value at every call to 'new Statix' static Object @ UNO; (new Object) @=> UNO; // DUE is set once after the first call to 'new Statix' static Object @ DUE; if (DUE == null) (new Object) @=> DUE; // TRE is set once when the file is loaded (see below) static Object @ TRE; <<< "at a: UNO=", Statix.UNO, "DUE=", Statix.DUE, "TRE=", Statix.TRE >>>; } <<< "at b: UNO=", Statix.UNO, "DUE=", Statix.DUE, "TRE=", Statix.TRE
; (new Statix) @=> Statix.TRE; <<< "at c: UNO=", Statix.UNO, "DUE=", Statix.DUE, "TRE=", Statix.TRE ;
===== file: t2.ck <<< "at d: UNO=", Statix.UNO, "DUE=", Statix.DUE, "TRE=", Statix.TRE
; new Statix @=> Statix @ _t1; <<< "at e: UNO=", Statix.UNO, "DUE=", Statix.DUE, "TRE=", Statix.TRE ; new Statix @=> Statix @ _t2; <<< "at f: UNO=", Statix.UNO, "DUE=", Statix.DUE, "TRE=", Statix.TRE ;
===== the output: % chuck t1.ck t2.ck at b: UNO= 0x0 DUE= 0x0 TRE= 0x0 at a: UNO= 0x5e5aa0 DUE= 0x5e5af0 TRE= 0x0 at c: UNO= 0x5e5aa0 DUE= 0x5e5af0 TRE= 0x5e6670 at d: UNO= 0x5e5aa0 DUE= 0x5e5af0 TRE= 0x5e6670 at a: UNO= 0x5e6ba0 DUE= 0x5e5af0 TRE= 0x5e6670 at e: UNO= 0x5e6ba0 DUE= 0x5e5af0 TRE= 0x5e6670 at a: UNO= 0x5e6c00 DUE= 0x5e5af0 TRE= 0x5e6670 at f: UNO= 0x5e6c00 DUE= 0x5e5af0 TRE= 0x5e6670
On 9 Dec 2009, at 02:11, Robert Poor wrote:
I now understand a bit more about initialization of static variables -- more accurately, about execution of top-level code -- and while it's not earth-shattering, I thought I'd pass it along. It may avoid some astonishment.
The rules are simple, but are different than I thought:
-- top level forms INSIDE a class definition are executed every time an instance of that class is created.
-- top level forms OUTSIDE of a class definition are executed once when the file loads.
Yes, that is what was discussed in the "static bug" thread. If one throws in some "static" data into the class for use with static functions, that data is not initialized until there has been an object of that class initialized. And the static data is probably re- initialized every time an new object is initialized. Also, it seems possible to use "static" outside a class, but I do not know the semantics. Hans
Hans: Thanks for the note -- you are correct that we discussed the fact that static objects may not be initialized until the class is instantiated. You CAN "throw some data into the class for use with static functions," and have that data initialized exactly once before an instance is created. The distinction is simply whether you place your top-level initializer inside or outside of the class definition. So this form: ===== public class Nutz { static Object @ CONST; } new Object @=> Nutz.CONST; ===== ...initializes Nutz.CONST exactly once -- even BEFORE an instance of Nutz is created. But this form: ===== public class Soup { static Object @ CONST; new Object @=> Soup.CONST; } ===== ...does NOT initialize Soup.CONST until an instance of Soup is created, and worse, it sets Soup.CONST to a new value every time a new instance is created. As I said, this is not a profound revelation, but it was the source of a devilish bug in my code and I thought I could spare someone the headache by pointing it out. That's all. - Rob On 9 Dec 2009, at 04:20, Hans Aberg wrote:
On 9 Dec 2009, at 02:11, Robert Poor wrote:
I now understand a bit more about initialization of static variables -- more accurately, about execution of top-level code -- and while it's not earth-shattering, I thought I'd pass it along. It may avoid some astonishment.
The rules are simple, but are different than I thought:
-- top level forms INSIDE a class definition are executed every time an instance of that class is created.
-- top level forms OUTSIDE of a class definition are executed once when the file loads.
Yes, that is what was discussed in the "static bug" thread. If one throws in some "static" data into the class for use with static functions, that data is not initialized until there has been an object of that class initialized. And the static data is probably re- initialized every time an new object is initialized.
Also, it seems possible to use "static" outside a class, but I do not know the semantics.
Hans
On 9 Dec 2009, at 17:20, Robert Poor wrote:
Thanks for the note -- you are correct that we discussed the fact that static objects may not be initialized until the class is instantiated.
You CAN "throw some data into the class for use with static functions," and have that data initialized exactly once before an instance is created. The distinction is simply whether you place your top-level initializer inside or outside of the class definition. So this form: ===== public class Nutz { static Object @ CONST; } new Object @=> Nutz.CONST; ===== ...initializes Nutz.CONST exactly once -- even BEFORE an instance of Nutz is created. But this form: ===== public class Soup { static Object @ CONST; new Object @=> Soup.CONST; } ===== ...does NOT initialize Soup.CONST until an instance of Soup is created, and worse, it sets Soup.CONST to a new value every time a new instance is created.
That is a good suggestion. Thanks.
As I said, this is not a profound revelation, but it was the source of a devilish bug in my code and I thought I could spare someone the headache by pointing it out. That's all.
I discovered it the same way. Because of the current being error prone, I hope 'chuck' is changed so that class "static" data is just name-spaced otherwise global. Hans
participants (2)
-
Hans Aberg
-
Robert Poor