Warning on uints and looping backwards through an array.

My coworker Todd Yard, just ran across a real interesting one.

Say you want to loop through an array. You generally go through it forwards:

[as]for(var i:Number = 0; i < arr.length; i++) { trace(i); }[/as] or backwards: [as]for(var i:Number = arr.length - 1; i >= 0; i–)
{
trace(i);
}[/as]

Array Looping 101, right? Works fine in AS1, AS2.

Enter AS3. Still works fine if i is typed to Number as above. Even works fine when i is typed to int.

Now let’s make i a uint. Whoa! Freeze! 15 second timeout! What happened? Think about it.

Say arr has one element.

First loop, i = 0 (length – 1). Trace 0.

Decrement i. If you are using ints or Numbers, i is now -1, the conditional fails and your loop exits. But in uints, there are no negative numbers. Decrement 0 and it rolls over to the maximum value of a uint, which is four billion something. That’s greater than or equal to zero, for sure, so the loop keeps going. Even if your machine was fast enough to execute four billion loops in one frame in under 15 seconds, once it hit zero again, it would start over at four billion. Result: hang, 15 second timeout.

Solution: use ints or Numbers when looping through an array backwards.

This entry was posted in Flash. Bookmark the permalink.

9 Responses to Warning on uints and looping backwards through an array.

  1. I actually fell in love with the new .map() and .filter() methods in AS3, it makes my code ‘more readable’ in a way 🙂

  2. Josh Tynjala says:

    I discovered this one a while back. I tend to use int on most of my for loops now.

  3. C4RL05 says:

    Is there any advantage of using uints instead of ints? Other than being able to count up to four billion instead of two.

  4. kp says:

    Well, using a uint also says, “this will always be zero or a positive number”. Since an array index is always >= 0, I tend to use uints for looping through arrays. I don’t think there is any technical advantage.

  5. Miha says:

    Thanks for the tip, should save at least one future bug I could encounter. You could offset the values by one more and then use i-1 in the array code or check if it reached 4 billion, but that’s just silly because apparently ints/Numbers are faster 🙂

  6. William C. says:

    Hm. Not sure what’s surprising about an unsigned integer being unsigned all the time.

  7. kp says:

    Nothing surprising about it at all. But uints are new to AS3, and sometimes us old time Flashers don’t consider all the ramifications of these newfangled contraptions.

  8. Anon says:

    Missing a – sign on your loop i–

    Probably bad practice to use an uint anytime you are subracting.

Leave a Reply