20

Running this code

var myValue1:int = 2;
switch (myValue1)
{
    case -3: trace(myValue1 + " == -3"); break;
    case -2: trace(myValue1 + " == -2"); break;
    case -1: trace(myValue1 + " == -1"); break;
    case 0:  trace(myValue1 + " == 0"); break;
    case 1:  trace(myValue1 + " == 1"); break;
    case 2:  trace(myValue1 + " == 2"); break;
    case 3:  trace(myValue1 + " == 3"); break;
    default: trace(myValue1 + " is unknown"); break;
}

var myValue2:int = -2;
switch (myValue2)
{
    case -3: trace(myValue2 + " == -3"); break;
    case -2: trace(myValue2 + " == -2"); break;
    case -1: trace(myValue2 + " == -1"); break;
    case 0:  trace(myValue2 + " == 0"); break;
    case 1:  trace(myValue2 + " == 1"); break;
    case 2:  trace(myValue2 + " == 2"); break;
    case 3:  trace(myValue2 + " == 3"); break;
    default: trace(myValue2 + " is unknown"); break;
}

gives this output:

2 == 0
-2 is unknown

(Compiled in Flash Builder 4.7.0.349722, running on Flash 11.5.502.149. Running in Windows 7 SP1, Firefox 18.0.2)

The following changes all fix the above problem, giving the correct output:

  • Changing the value-type to Number.
  • Removing the negative-number case statements.
  • Changing the case statements to use int-variables rather than literals... unless those variables are also const, in which case it stays broken!

Changing myValue2 = -1 gives the output -1 == -3, which is equally wtf-ish.


Clearly this is a bug, but... what causes it? Is there some subtle nuance of using int or negative numbers in case-statements that I don't understand? Is my code somehow wrong? Or is this simply an issue with the bytecode-compiler in Flash Builder?

BlueRaja - Danny Pflughoeft
  • 84,206
  • 33
  • 197
  • 283
  • 1
    Posted code works properly for me in Flash CS5 and FB4.7. Output: 2 == 2 -2 == -2 –  Feb 07 '13 at 22:53
  • 1
    I don't have an answer, but I often do something like this instead of a bunch of if/else statements `switch (true) { case someBooleanExpression: break; case someOtherExpression: break; }` I think the answer to this behavior lies in that somehow stuff is getting coerced/being treated as a boolean. But I can't give a definitive answer, I'm sure someone else will :) – Sunil D. Feb 07 '13 at 22:58
  • 4
    Interesting. FYI, I get the same result in Flash Builder 4.7 building for AIR 3.4 (which I guess is using Flash Player 11.4). However, it traces `2 == 2` and `-2 == -2` in Flash Professional CS6 compiling for Flash Player 9, 10.3, 11.1, 11.2, 11.3, and 11.4. – david.emilsson Feb 07 '13 at 23:04
  • I have Flash builder 4.6 (sdk 4.6) and it traces `2 == 2` and `-2 == -2` – PCM Feb 07 '13 at 23:41
  • @walkietokyo: Perhaps I am confusing terminology. The project is a Flex project (which uses the "Air SDK"), but it runs in the browser as an embedded swf. I thought "Air" was a separate thing that ran on the desktop. So am I running an Air applet rather than a flash applet, then? – BlueRaja - Danny Pflughoeft Feb 07 '13 at 23:45
  • @BlueRaja-DannyPflughoeft It's using the Air SDK when creating a "Pure ActionScript" project, even if it's for the web. I guess this is out of convenience because it contains the ActionScript compiler anyway. However, I just discovered that when debugging in the browser I'm using the Flash Player Debugger 11.5.502.146 so even though it's (probably) compiling using FP 11.4, the bug can still be in Flash Player 11.5.x – david.emilsson Feb 07 '13 at 23:53
  • 1
    Flash CS5: `2 == 2` and `-2 == -2` MiniBuilder `2 == 2` and `-2 == -2` wonderfl.net `2 == 2` and `-2 == -2` – khailcs Feb 08 '13 at 04:22
  • Flash cs6... FP 11.2.202.228 (12.0) working fine. – Bimawa Feb 12 '13 at 15:10
  • As it worked properly on a project of mine, try copying your code into another flash file . Because in this case flash may have bugged while doing something with your project – Nicolas Sleiman Feb 12 '13 at 04:45
  • a wild guess: have you tried to use explicit constructors and method calls? specifically, `var myValue2:int = new int(-2);`, `switch (myValue2.valueOf())` and `trace(myValue2.toString() + " == -2")`? – collapsar Feb 12 '13 at 19:32
  • Another wild guess: If you add on the second `switch` statement `case -4: trace(myValue2 + " == -4"); break;`, does it show it? Probably the bug is subtracting 2 somewhere. At least, it seems consistent with the results you have so far. – A. Rodas Feb 12 '13 at 22:25
  • 2
    To determine if it's a Flash Player bug or a compiler bug, try to change versions of each to determine where the problem comes from. In case of the compiler being incriminated, you could try to use a tool like SWFInvestigator to see the output bytecode (and what's wrong with it). – Antoine Lassauzay Feb 13 '13 at 14:55
  • @Sunil I have never thought about that before; great idea! – Panzercrisis Feb 13 '13 at 19:10
  • Antoine is Mr right. This compiles correctly on FB 4.6 -- inside SWFInvestigator: pushbyte -2, etc etc etc – ansiart Feb 15 '13 at 20:40
  • If you really want an answer, you should post the SWF. It seems like many people here, including me, can't reproduce the problem. – Sean Fujiwara Feb 18 '13 at 22:36

3 Answers3

1

I don't think you will find a concrete answer to this question. What I can offer is a confirmation of the AS3 compiler bugginess. I spent quite some time trying to resolve similar 'magical' errors and came up empty. One such example is a For and While loops skipping the first or last item in an Array for no apparent reason while a Foreach looped worked just fine.

To me the most plausible reason for that is an error in memory management. It might also be hardware related since the frequency of such things happening was higher on some machines that I or my colleagues worked on. What I think is that some 'invisible' conditions are met e.g. order of performed operations ( you could try putting some dummy code in between the var declaration and the switch or maybe assigning the var value couple more times, just to 'jog the memory') that combined with the error-prone compiler mess up the memory addressing and your switch thinks its compering two integers while in reality it got a different value from the memory.

qiuntus
  • 38
  • 6
1

You can probably force the compiler's hand by converting the original value to a String and making your cases into String values.

switch( String(value) )
{
   case "-3": /*do something*/; break;
   case "-2": /*do something*/; break;
   case "-1": /*do something*/; break;
   case  "0": /*do something*/; break;
   case  "1": /*do something*/; break;
   case  "2": /*do something*/; break;
   case  "3": /*do something*/; break;
   default: break;
}
Nathan
  • 87
  • 4
1

This is simply an issue with the bytecode-compiler in Flash Builder.

Clearly, your syntax is fine; there are literally hundreds of known issues with the compiler dating back to 2005 that are still open or unresolved.

cleverbit
  • 5,514
  • 5
  • 28
  • 38