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.