Switch case weird scoping

前端 未结 2 1109
我寻月下人不归
我寻月下人不归 2020-12-02 21:27

Reviewing some 3rd party C code I came across something like:

switch (state) {
case 0: 
    if (c==\'A\') { // open brace
        // code...
    break; // br         


        
相关标签:
2条回答
  • 2020-12-02 21:53

    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 breaks 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.

    0 讨论(0)
  • 2020-12-02 22:01

    In C and C++ it is legal to jump into loops and if blocks so long as you don't jump over any variable declarations. You can check this answer for an example using goto, but I don't see why the same ideas wouldn't apply to switch blocks.

    The semantics are different than if the } was above case 1 as you would expect.
    This code actually says if state == 0 and c != 'A' then go to case 2 since that's where the closing brace of the if statement is. It then processes that code and hits the break statement at the end of the case 2 code.

    0 讨论(0)
提交回复
热议问题