Acknowledged
CIQQA-3581

Casting Float to Number does not yield Number

This code:

var myFloat = 5.0;
var myNumber = myFloat as Number;
var mod = myNumber % 1;

Compiles without warnings, but crashes at runtime with:

Error: Unhandled Exception
Exception: UnexpectedTypeException: Expected Number/Long, given Number/Float

As far as I can tell:

  • this behavior is undocumented
  • the types "Number/Long" and "Number/Float" are undocumented
  • the effects of casting numeric types are undocumented

Consequently I'm not sure how to characterize this bug. If it's expected, this is a documentation bug. If it's not expected, this is a runtime and/or compiler bug.

I read the relevant section on "type casting" in the SDK docs. I've reproduced the totality of the documentation on type casting here:

The as keyword can also be used in an expression to type cast a value to another type. This can be useful if the type is not clear to the type system.

This, unfortunately, does not help very much.

---

Tested on Descent G1 & G2 simulators

SDK 8.3.0

Parents
  • Btw Monkey C has both run-time and compile-time types, which are related but not identical.

    Run-time types existed in Monkey C from the beginning, while compile-time types / type checking were only introduced a few years ago.

    Obviously if you have 0 casts in your code, then assuming there are no bugs in the type checker, the compile-time type should at least not contradict the run-time type. Although the compile-time type may be *vaguer* then the run-time type - like the compile-time return type of loadResource() being a generic Resource, as opposed to a specific resource type like BitmapResource.

    But there have been bugs in the API type definitions, where values in the API have had the wrong compile-time types (e.g. Number instead of Float or Number). And there are known issues where the compile-time type for values in a container (like Array or Dictionary) can be wrong, since the type checker sometimes doesn't take into account the fact that you can change/add elements of a different type than the existing elements in the container.

    So it's definitely not like a strongly typed language (like Java or Swift), where the compile-time type system is almost infallible (in the absence of casts).

Comment
  • Btw Monkey C has both run-time and compile-time types, which are related but not identical.

    Run-time types existed in Monkey C from the beginning, while compile-time types / type checking were only introduced a few years ago.

    Obviously if you have 0 casts in your code, then assuming there are no bugs in the type checker, the compile-time type should at least not contradict the run-time type. Although the compile-time type may be *vaguer* then the run-time type - like the compile-time return type of loadResource() being a generic Resource, as opposed to a specific resource type like BitmapResource.

    But there have been bugs in the API type definitions, where values in the API have had the wrong compile-time types (e.g. Number instead of Float or Number). And there are known issues where the compile-time type for values in a container (like Array or Dictionary) can be wrong, since the type checker sometimes doesn't take into account the fact that you can change/add elements of a different type than the existing elements in the container.

    So it's definitely not like a strongly typed language (like Java or Swift), where the compile-time type system is almost infallible (in the absence of casts).

Children
No Data