Array index bounds checking?

Haxe (targetting HashLink) allows me to do this:

var a = [15, 16, 17];
var x1 = a[3];  // Whoops!
var x2 = a[-3]; // Well, now you're just being crazy.
trace(x1); // What?? (0)
trace(x2); // Same as above.

I’d assumed that would be a compilation error. Why is that not an error?

Is there a way I can have Haxe warn me about it? I didn’t see anything in the manual’s compiler usage chapter nor in the global compiler flags chapter.

Here is Array spec in Haxe, which explains reading/writing out of bounds: Array - Haxe - The Cross-platform Toolkit
You can use an abstract on top of Array to check bounds on each read/write access. Something like this: Safety/SafeArray.hx at master · RealyUniqueName/Safety · GitHub

I missed that in the manual. Thanks, Aleksandr.

The manual says, “Since array access in Haxe is unbounded, i.e. it is guaranteed to not throw an exception, {snip}”. Any idea the rationale for that? It seems like it would be much safer for the compiler to spot any infraction it can at compile time and complain loudly about it.

I’d think it would be useful if I could pass a flag to the compiler to tell it to be as paranoid as possible during development. Has Haxe ever had a flag to enable array index bounds checking? Any plans for one?

It can be pretty covenient that you can just do something like this:

var element = array[index];
if (element != null) {
    // do something with it
}

Rather than having to check the index beforehand, which seems more cumbersome / error-prone.

Well, one can invent a reason after the fact, but the truth of the matter is that that’s how it behaved for flash and js and changing the behavior to anything different would decrease performance.

1 Like

Gama11, I see that works for other objects, but for an array of Ints or Bools, putting in an out-of-bounds index gives me 0 or false, respectively.

I can also see that, given usual patterns of accessing arrays, maybe it’s not so common anyway to pull an array index out of the sky and need to check it before use.

I’m not familiar with what’s under the hood, but I don’t want to confuse:

  • optional compile-time checking, with
  • runtime checks

When I made the array indexing error in my experimenting, it was something I’d assume would be caught at compile-time (compilation performance penalty), not at run-time.

Consider this code:

var a = [1, 2, 3];
trace(a[someFunction()]);

Depending on the return value, this code will read out of bounds or not. Reading out of bounds is well defined behavior and so the compiler will also allow it. If this were disallowed at compile time only for the most trivial cases, then it would lead to confusion for all other cases.

1 Like