137

I want to jump from the middle of a switch statement, to the loop statement in the following code:

while (something = get_something())
{
    switch (something)
    {
    case A:
    case B:
        break;
    default:
        // get another something and try again
        continue;
    }
    // do something for a handled something
    do_something();
}

Is this a valid way to use continue? Are continue statements ignored by switch statements? Do C and C++ differ on their behaviour here?

7
  • Your idea is fine but the loop above will never execute do_something(). Commented Jan 27, 2010 at 12:28
  • 8
    Even if control reaches case A or case B? Commented Jan 27, 2010 at 12:33
  • 30
    I was going to say, antik is wrong about that. In the case of A or B then do_something() will execute. With default it will bail. Commented Jan 27, 2010 at 12:37
  • 3
    @acron, that's the intended behaviour Commented Jan 27, 2010 at 13:29
  • 1
    I think this looks far more suspicious & confusing and therefore more harmful than a goto. Commented Nov 16, 2013 at 14:37

6 Answers 6

74

It's fine, the continue statement relates to the enclosing loop, and your code should be equivalent to (avoiding such jump statements):

while (something = get_something()) {
    if (something == A || something == B)
        do_something();
}

But if you expect break to exit the loop, as your comment suggest (it always tries again with another something, until it evaluates to false), you'll need a different structure.

For example:

do {
    something = get_something();
} while (!(something == A || something == B));
do_something();
Sign up to request clarification or add additional context in comments.

5 Comments

'equivalent' only in the semantic sense. the code the compiler generates is very different. with a switch statement, the compiler can generate a jump table which avoids multiple comparisons and thus is much faster than comparing against each element 1 by 1.
@chacham15, why couldn't the compiler generate the same code for both?
@avakar switch statements generate jump tables whereas the other representation is a series of logical evaluations. google jump table for more information.
@chacham15, what prevents the compiler from generating a jump table for the two if statements or a series of logical evaluations for the switch?
@avakar switch statements require the cases to be constant values, because that is not the case with if statements, it cannot make the same optimization (note: i am speaking in the general case, it is possible given certain requirements (e.g. const values only, only certain logical operators, etc.) to make the optimization, but it is highly compiler dependent and YMMV).
42

Yes, continue will be ignored by the switch statement and will go to the condition of the loop to be tested. I'd like to share this extract from The C Programming Language reference by Ritchie:

The continue statement is related to break, but less often used; it causes the next iteration of the enclosing for, while, or do loop to begin. In the while and do, this means that the test part is executed immediately; in the for, control passes to the increment step.

The continue statement applies only to loops, not to a switch statement. A continue inside a switch inside a loop causes the next loop iteration.

I'm not sure about that for C++.

Comments

21

Yes, it's OK - it's just like using it in an if statement. Of course, you can't use a break to break out of a loop from inside a switch.

7 Comments

But if has no effect on the behaviour of continue or break. How do you mean it's alike?
@Matt I mean it will continue the loop in both cases.
@Neil, okay, confusion averted.
@KiJéy I can't find any reference for this, and in many years of C programming I have never seen any compiler that supports this... Where on earth did you find this?
Wow sorry, I saw this in PHP, thought it was an old practice, turns out it's just PHP...
|
10

It's syntactically correct and stylistically okay.

Good style requires every case: statement should end with one of the following:

 break;
 continue;
 return (x);
 exit (x);
 throw (x);
 //fallthrough

Additionally, following case (x): immediately with

 case (y):
 default:

is permissible - bundling several cases that have exactly the same effect.

Anything else is suspected to be a mistake, just like if(a=4){...} Of course you need enclosing loop (while, for, do...while) for continue to work. It won't loop back to case() alone. But a construct like:

while(record = getNewRecord())
{
    switch(record.type)
    {
        case RECORD_TYPE_...;
            ...
        break;
        default: //unknown type
            continue; //skip processing this record altogether.
    }
    //...more processing...
}

...is okay.

4 Comments

sorry for necroposting, but I would add that a call to exit would also usually be a fine thing to end a switch case with.
Well, I am going to got all Dr. Frankenstein here and also point out that default: does not have to be the last/bottom entry - as this question points out...
@SlySven: Lexically, it doesn't, but if you don't have a good reason not to make it last, do make it last. It's often confusing if used at other places.
@SF. well, I can easily imagine the cases when it would make more sense to make default: case the first instead of the last. Like "do this, unless you get the following unusual values, which should be handled as follows".
8

While technically valid, all these jumps obscure control flow -- especially the continue statement.

I would use such a trick as a last resort, not first one.

How about

while (something = get_something())
{
    switch (something)
    {
    case A:
    case B:
        do_something();
    }        
}

It's shorter and perform its stuff in a more clear way.

2 Comments

sorry for the confusion Alexander, the code is for demonstration only, i have good reason (i believe) for the actual structure in my code.
@Matt: That would probably mean an even more obfuscated structure... :)
-5

Switch is not considered as loop so you cannot use Continue inside a case statement in switch...

1 Comment

The switch statement is inside a while loop, so continue is perfectly valid.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.