Acknowledged

Strange results with class constants

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.
Parents Comment Children
No Data