Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is using if (0) to skip a case in a switch supposed to work?

I have a situation where I would like for two cases in a C++ switch statement to both fall through to a third case. Specifically, the second case would fall through to the third case, and the first case would also fall through to the third case without passing through the second case.

I had a dumb idea, tried it, and it worked! I wrapped the second case in an if (0) { ... }. It looks like this:

#ifdef __cplusplus
#  include <cstdio>
#else
#  include <stdio.h>
#endif

int main(void) {
    for (int i = 0; i < 3; i++) {
        printf("%d: ", i);
        switch (i) {
        case 0:
            putchar('a');
            // @fallthrough@
            if (0) {        // fall past all of case 1 (!)
        case 1:
            putchar('b');
            // @fallthrough@
            }
        case 2:
            putchar('c');
            break;
        }
        putchar('\n');
    }
    return 0;
}

When I run it, I get the desired output:

0: ac
1: bc
2: c

I tried it in both C and C++ (both with clang), and it did the same thing.

My questions are: Is this valid C/C++? Is it supposed to do what it does?

like image 891
Mark Adler Avatar asked Oct 05 '22 04:10

Mark Adler


People also ask

Can we use 0 in switch case?

using Switch is like == in "if statement" and not === (doesn't check for type). Only empty string or NULL would result in an Integer 0 - other than that, they are considered string 0.

What happens if there is no break statement in a switch case in any of the cases?

Without break , the program continues to the next labeled statement, executing the statements until a break or the end of the statement is reached. This continuation may be desirable in some situations. The default statement is executed if no case constant-expression value is equal to the value of expression .

Should I use if or switch case?

Use switch every time you have more than 2 conditions on a single variable, take weekdays for example, if you have a different action for every weekday you should use a switch. Other situations (multiple variables or complex if clauses you should Ifs, but there isn't a rule on where to use each.

Does switch case need break if return?

No, you don't need a break in a switch case statement. The break is actually optional, but use with caution. Show activity on this post.


3 Answers

Yes, this is supposed to work. The case labels for a switch statement in C are almost exactly like goto labels (with some caveats about how they work with nested switch statements). In particular, they do not themselves define blocks for the statements you think of as being "inside the case", and you can use them to jump into the middle of a block just like you could with a goto. When jumping into the middle of a block, the same caveats as with goto apply regarding jumping over initialization of variables, etc.

With that said, in practice it's probably clearer to write this with a goto statement, as in:

    switch (i) {
    case 0:
        putchar('a');
        goto case2;
    case 1:
        putchar('b');
        // @fallthrough@
    case2:
    case 2:
        putchar('c');
        break;
    }
like image 62
R.. GitHub STOP HELPING ICE Avatar answered Oct 16 '22 11:10

R.. GitHub STOP HELPING ICE


Yes, this is allowed, and it does what you want. For a switch statement, the C++ standard says:

case and default labels in themselves do not alter the flow of control, which continues unimpeded across such labels. To exit from a switch, see break.

[Note 1: Usually, the substatement that is the subject of a switch is compound and case and default labels appear on the top-level statements contained within the (compound) substatement, but this is not required. Declarations can appear in the substatement of a switch statement. — end note]

So when the if statement is evaluated, control flow proceeds according to the rules of an if statement, regardless of intervening case labels.

like image 59
cigien Avatar answered Oct 16 '22 12:10

cigien


As other answers have mentioned, this is technically allowed by the standard, but it is very confusing and unclear to future readers of the code.

This is why switch ... case statements should usually be written with function calls and not lots of inline code.

switch(i) {
case 0:
    do_zero_case(); do_general_stuff(); break;
case 1:
    do_one_case(); do_general_stuff(); break;
case 2:
    do_general_stuff(); break;
default:
    do_default_not_zero_not_one_not_general_stuff(); break;
}
like image 28
Pete Becker Avatar answered Oct 16 '22 12:10

Pete Becker