Not only is it valid, similar structure has been used in real code, e.g., Duff's Device, which is an unrolled loop for copying a buffer:
send(to, from, count)
register short *to, *from;
register count;
{
register n = (count + 7) / 8;
switch(count % 8) {
case 0: do { *to = *from++;
case 7: *to = *from++;
case 6: *to = *from++;
case 5: *to = *from++;
case 4: *to = *from++;
case 3: *to = *from++;
case 2: *to = *from++;
case 1: *to = *from++;
} while(--n > 0);
}
}
Since a switch
statement really just computes an address and jumps to it, it's easy to see why it can overlap with other control structures; the lines within other control structures have addresses that can be jump targets, too!
In the case you presented, imagine if there were no switch
or break
s in your code. When you've finished executing the then
portion of a if
statement, you just keep going, so you'd fall through into the case 2:
. Now, since you have the switch
and break
, it matters what break
can break out of. According to the MSDN page, “The C break statement”,
The break statement terminates the execution of the nearest enclosing do, for, switch, or while statement in which it appears. Control passes to the statement that follows the terminated statement.
Since the nearest enclosing do, for, switch, or while statement is your switch (notice that if is not included in that list), then if you're inside the then
block, you transfer to the outside of the switch
statement. What's a bit more interesting, though, is what happens if you enter case 0
, but c == 'A'
is false. Then the if
transfers control to just after the closing brace of the then
block, and you start executing the code in case 2
.
switch-case
's oddgoto label
implementation. While your particular case is probably a bit weird and hard to come up with a use case for (look at Duff's Device, though), the general concept of fall-through cases (when you leave away thebreak
) can indeed be quite useful. – Synchrocase 1:
is being treated by the compiler as a seperate label. The syntax is perfectly valid, but almost certainly (from the context) a logic error in this situation. Test it by sendingstate ==1
through and you will see the incorrect result. – Liability