A few years ago, Lexikos wrote:
Static declarations are processed in the order that the pre-parser encounters them - top to bottom. Static declarations are not subject to control flow.
("http://www.autohotke...ed/#entry552863")
I accept that this behaviour is either by design (i.e., it’s somehow preferable) or required by internal limitations that would be difficult to eliminate.
Nonetheless, I find it rather unintuitive, enough so to warrant a warning being issued when the initialisation of a static variable references another static that has not yet been initialised. Such a warning is indeed issued for function statics but apparently not for class static data members.
Here is an example:
#Warn All , MsgBox Show( vLocation , vName , vValue ) { MsgBox , % Format( "Location #{1:d}: {2:s} = {3:d}" , vLocation , vName , vValue ) } ; Test case #1: accessing a function's uninitialised static local variable. f1() { static v1 := f2( 1 ) Show( 2 , "f1.v1" , v1 ) } f2( vLocation ) { static v1 := 123 Show( vLocation , "f2.v1" , v1 ) ; line 019: warning. return v1 } f3() { static v1 := f2( 3 ) Show( 4 , "f3.v1" , v1 ) } ; Test case #2: accessing a class' uninitialised static data member. f4() { static v1 := (new C1( 5 )).p1 Show( 6 , "f4.v1" , v1 ) } class C1 { static k1 := 123 __New( vLocation ) { base.__New() Show( vLocation , "C1.k1" , C1.k1 ) ; No warning here. } p1 { get { return C1.k1 } } } f5() { static v1 := (new C1( 7 )).p1 Show( 8 , "f5.v1" , v1 ) } MsgBox , % "All statics have been initialised." f1() f3() f4() f5() return
This produces the following output:
Warning: line 019: v1 (a static variable) has not been assigned a value. Location #1: f2.v1 = 0 Location #3: f2.v1 = 123 Location #5: C1.k1 = 0 Location #7: C1.k1 = 123 All statics have been initialised. Location #2: f1.v1 = 0 Location #4: f3.v1 = 123 Location #6: f4.v1 = 0 Location #8: f5.v1 = 123
The output is consistent with the assertion that static definitions are processed in parsing order and not based on execution flow.
However, note the warning issued about ‘f2.v1’ (line 019): the parser has detected that the static variable is read before its definition is processed (coming from location #1). The warning may be a bit confusing (for those who expect static definitions to follow execution flow) but still helpful (perhaps a more specific warning could be substituted in the future).
On the other hand, no such warning was issued for ‘C1.k1’ at location #5. Isn’t it essentially the same situation? The static was read before being assigned a value, hence the zero value. So a similar warning would have been helpful.
Thanks!