Tricky unsafe cast is too tricky

Important: this article is written about Haxe 3.1.3. It works well in Haxe 3.2 🙂

Few days ago I wrote about eight things I don’t like in Haxe, and one of thing was tricky unsafe cast syntax:

(cast findViewById(R.id.myTextView):TextView).setText("Cool");

compared to safe cast:

cast(findViewById(R.id.myTextView), TextView).setText("Cool");

However I was wrong. This unsafe cast work fine only on dynamic targets, but on cpp it cause compilation error:

class A {
    public function new() {
    }
}

class B extends A {
    public function foo():Void {
        trace("foo");
    }
}

class Test {
    private static function bar(a:A):Void {
        (cast a:B).foo();
    }

    public static function main() {
        bar(new B());
    }
}

work fine for neko, javascript or flash, but on cpp:

error: no member named 'foo' in 'A_obj'

🙁

UPD: As mentioned here, Std.instance() should be used as one-line unsafe cast. However this is not true:

haxe - Std.instance(a, B).foo();
js - ((a instanceof B) ? a : null).foo();
cpp - ::Std_obj::instance(a, hx::ClassOf<::B>())->__Field(HX_CSTRING("foo"), true)();

Pretty much cpp code, and additional check in js code 🙁 . Compare to unsafe cast:

haxe - var b:B = cast a; b.foo();
js - var b = a; b.foo();
cpp - ::B b = a; b->foo();

Nice 🙂

By the way, this is code generated by the safe cast:

haxe - cast(a, B).foo();
js - (js.Boot.__cast(a , B)).foo();
cpp - (hx::TCast<B>::cast(a))->foo();

For cpp it is even better than Std.instance().

Leave a Reply

Your email address will not be published. Required fields are marked *

*

This site uses Akismet to reduce spam. Learn how your comment data is processed.