(updated) llvm-gcc strange behavior
Today compiling with XCode 4.2.1 ... i found this.. the syntax is right... ¿have the switch instruction a limitation about this? YES
ARM and x86 architecture supports 'nop' instruction...
In Switch-Case statement, you can't declare variables inside, the 'cases' are translated to jump to memory address (some bytes after normally) in case of jump, the stack is not re-framed, like a simple "goto" basic instruction ("jmp" in asembler) is used to go to the correct memory address, when this instruction ends, the stack is returned "as is", with some bytes more of allocations in them, causing unexpected BAD_ACCESS & other low level errors.
Never allocate in switch case ;-) "learn from mistakes"
Posted at BinaryCell
This is a weird thing caused by the switch-statement in C.
ReplyDeleteTo understand the reason we need to see how the (only relevant for the current discussion) statements are defined in the C language:
select-statement → if (expression) statement
→ if (expression) statement else statement
→ switch (expression) statement
jump-statement → goto identifier ;
→ continue ;
→ break ;
→ return ;
→ return expression ;
labeled-statement → identifier : statement
→ case expression : statement
→ default: statement
compound-statement → { statement-seq }
(Here statement-seq means a sequence of statements of C, including but not limiting to all those shown above)
switch is normally used like this
switch (e)
{
case A:
statement1;
statement2
break;
}
Note two things in the code above: there is a compound-statement right after the switch (otherwise you would only be able to write a single statement!). Thus, inside a compound statement there is a statement-seq (a sequence of statements). The first one, is, interestingly, a labeled-statement, the remaining ones are two statements and then there is a break statement.
Do you see the pattern. That 'case A' is only related to statement1. statement2 is just the next statement inside the compound-statement we usually write after a switch.
This leads to strange things like
switch (e)
{
case A:
int tmp = ... ;
statement1;
break;
case B:
int tmp = ...; // ← error! tmp redeclared
statement2;
}
which makes sense, since you wrote something that conceptually is like
{
A: int tmp = ...; // A here would be a label-name
statement1;
goto END; // This would be the break;
B: int tmp = ...; // B here would be a label-name
statement2;
END:
}
so to solve this problem you should do
switch (e)
{
case A:
{
// Open here a compound-statement
int tmp = ...;
break; // Or right after the closing } of the compound-statement, it doesn't matter
}
// You could put the break here as well
case B:
{
// Open here a compound-statement
int tmp = ...; // Look ma, no problems!
break;
}
...
}
And you know what? Such weird thing is present in C++ (obviously) and Java as well!