Using continue in a switch statement

143,485

Solution 1

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();

Solution 2

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

Solution 3

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.

Solution 4

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.

Solution 5

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.

Share:
143,485

Related videos on Youtube

Matt Joiner
Author by

Matt Joiner

About Me I like parsimonious code, with simple interfaces and excellent documentation. I'm not interested in enterprise, boiler-plate, or cookie-cutter nonsense. I oppose cruft and obfuscation. My favourite languages are Go, Python and C. I wish I was better at Haskell. Google+ GitHub Bitbucket Google code My favourite posts http://stackoverflow.com/questions/3609469/what-are-the-thread-limitations-when-working-on-linux-compared-to-processes-for/3705919#3705919 http://stackoverflow.com/questions/4352425/what-should-i-learn-first-before-heading-to-c/4352469#4352469 http://stackoverflow.com/questions/6167809/how-much-bad-can-be-done-using-register-variables-in-c/6168852#6168852 http://stackoverflow.com/questions/4141307/c-and-c-source-code-profiling-tools/4141345#4141345 http://stackoverflow.com/questions/3463207/how-big-can-a-malloc-be-in-c/3486163#3486163 http://stackoverflow.com/questions/4095637/memory-use-of-stl-data-structures-windows-vs-linux/4183178#4183178

Updated on July 08, 2022

Comments

  • Matt Joiner
    Matt Joiner almost 2 years

    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?

    • antik
      antik over 14 years
      Your idea is fine but the loop above will never execute do_something().
    • Alexander Poluektov
      Alexander Poluektov over 14 years
      Even if control reaches case A or case B?
    • Antony Woods
      Antony Woods over 14 years
      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.
    • Matt Joiner
      Matt Joiner over 14 years
      @acron, that's the intended behaviour
    • Antony Woods
      Antony Woods over 14 years
      Yeah, I know :) Was correcting antik's comment.
    • phoeagon
      phoeagon over 10 years
      I think this looks far more suspicious & confusing and therefore more harmful than a goto.
    • Yan Zhou
      Yan Zhou over 7 years
      I don't see any problem with your code. Perhaps check if the input does get to the default branch? Maybe you can provide a more complete example that can reproduce your problem.
  • Matt Joiner
    Matt Joiner over 14 years
    But if has no effect on the behaviour of continue or break. How do you mean it's alike?
  • Matt Joiner
    Matt Joiner over 14 years
    sorry for the confusion Alexander, the code is for demonstration only, i have good reason (i believe) for the actual structure in my code.
  • visitor
    visitor over 14 years
    @Matt: That would probably mean an even more obfuscated structure... :)
  • Admin
    Admin over 14 years
    @Matt I mean it will continue the loop in both cases.
  • Matt Joiner
    Matt Joiner over 14 years
    @Neil, okay, confusion averted.
  • Tim Schaeffer
    Tim Schaeffer over 14 years
    I think it is still confusing.
  • chacham15
    chacham15 over 10 years
    '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.
  • Vality
    Vality over 9 years
    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.
  • avakar
    avakar over 9 years
    @chacham15, why couldn't the compiler generate the same code for both?
  • chacham15
    chacham15 over 9 years
    @avakar switch statements generate jump tables whereas the other representation is a series of logical evaluations. google jump table for more information.
  • avakar
    avakar over 9 years
    @chacham15, what prevents the compiler from generating a jump table for the two if statements or a series of logical evaluations for the switch?
  • chacham15
    chacham15 over 9 years
    @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).
  • Rick
    Rick almost 7 years
    The switch statement is inside a while loop, so continue is perfectly valid.
  • Mouradif
    Mouradif over 6 years
    you can use break to break out of a loop from inside a switch just like you can break out of an outer loop from inside an inner loop like this : break 2; or break 3; to go up another level etcetera...
  • arjunyg
    arjunyg about 6 years
    @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?
  • Mouradif
    Mouradif about 6 years
    Wow sorry, I saw this in PHP, thought it was an old practice, turns out it's just PHP...
  • SlySven
    SlySven over 5 years
    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...
  • SF.
    SF. over 5 years
    @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.
  • Geoffrey
    Geoffrey over 4 years
    This is NOT a PHP question.
  • Ruslan
    Ruslan almost 4 years
    @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".