Given
module Tests { class X { const K1 = 1; } class Y extends X { function initialize() { X.initialize(); } const K2 = K1 + 1; static function getK1() as Number { return K1; } static function getK2() as Number { return K2; } } (:test) function test1(logger as Logger) as Boolean { logger.debug("K1="+X.K1); logger.debug("K2="+Y.K2); return X.K1 == 1 && Y.K2 == 2; } (:test) function test2(logger as Logger) as Boolean { logger.debug("K1="+Y.getK1()); return Y.getK1() == 1; } (:test) function test3(logger as Logger) as Boolean { logger.debug("K2="+Y.getK2()); return Y.getK2() == 2; } (:test) function test4(logger as Logger) as Boolean { var y = new Y(); logger.debug("K1="+y.K1); logger.debug("K2="+y.K2); return y.K1 == 1 && y.K2 == 2; } }
The type checker reports no issues at Strict, but:
- test1 fails because Y.K2 == null. Apparently, it wasn't initialized at runtime.
- test2 crashes, because the lookup of K1 in getK1 fails. Maybe because its in the base class?
- test3 crashes, because the lookup of K2 in getK2 fails. So you just can't lookup constants in static methods
- test4 passes. So in a non-static method K1 and K2 have the right values.
I get the same results with 4.1.5 and earlier, and with 4.1.6 at O0 or O1. If I use 4.1.6 at O2 all the tests pass. Evidently the optimizer expects all those expressions to be valid, and to have the obvious values.
After some more digging I wondered if perhaps the problem was that the consts need to be static. But if I do that I get:
Executing test Tests.test1... DEBUG (12:36): K1=1 Error: Symbol Not Found Error Details: Could not find symbol 'K1' Stack: - <init>() at test.mc:128 0x100008e8 - test1() at test.mc:139 0x1000094f - evaluate_test_entries_0_to_5() at UnitTests.mc:48 0x100006b0 - runTest() at UnitTests.mc:69 0x10000799 ERROR
for each of test1 through test4. And I get the same result with or without -O2.
So I guess I'm saying:
- The type checker thinks things work the way I expected them to work
- The optimizer thinks things work the way I expected them to work
- The runtime disagrees with all of us
- static const in a class seems to be totally broken. Im not even sure what its supposed to mean. Perhaps a static const is supposed to be initialized at program startup, while a non-static const is initialized when the corresponding instance of the class is created; but that would only matter if the initializer depended on mutable state. And doesn't explain why X.K1 (a non-static const) seems to have the correct value at runtime, even without a instance of the class, but Y.K2 does not.