Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to break out of a loop from inside a switch?

People also ask

How do you break out of a loop?

To break out of a for loop, you can use the endloop, continue, resume, or return statement.

Can switch be used inside for loop?

It is not necessarily an antipattern to use a switch statement within a loop—it is only considered incorrect when used to model a known sequence of steps. The most common example of the correct use of a switch within a loop is an inversion of control such as an event handler.

Does Break Break out of switch?

There's no such thing as breaking out of an if . break applies only to switch and to loops in all the programming languages I'm familiar with. PHP: break ends execution of the current for, foreach, while, do-while or switch structure.


You can use goto.

while ( ... ) {
   switch( ... ) {
     case ...:
         goto exit_loop;

   }
}
exit_loop: ;

An alternate solution is to use the keyword continue in combination with break, i.e.:

for (;;) {
    switch(msg->state) {
    case MSGTYPE:
        // code
        continue; // continue with loop
    case DONE:
        break;
    }
    break;
}

Use the continue statement to finish each case label where you want the loop to continue and use the break statement to finish case labels that should terminate the loop.

Of course this solution only works if there is no additional code to execute after the switch statement.


Premise

The following code should be considered bad form, regardless of language or desired functionality:

while( true ) {
}

Supporting Arguments

The while( true ) loop is poor form because it:

  • Breaks the implied contract of a while loop.
    • The while loop declaration should explicitly state the only exit condition.
  • Implies that it loops forever.
    • Code within the loop must be read to understand the terminating clause.
    • Loops that repeat forever prevent the user from terminating the program from within the program.
  • Is inefficient.
    • There are multiple loop termination conditions, including checking for "true".
  • Is prone to bugs.
    • Cannot easily determine where to put code that will always execute for each iteration.
  • Leads to unnecessarily complex code.
  • Automatic source code analysis.
    • To find bugs, program complexity analysis, security checks, or automatically derive any other source code behaviour without code execution, specifying the initial breaking condition(s) allows algorithms to determine useful invariants, thereby improving automatic source code analysis metrics.
  • Infinite loops.
    • If everyone always uses while(true) for loops that are not infinite, we lose the ability to concisely communicate when loops actually have no terminating condition. (Arguably, this has already happened, so the point is moot.)

Alternative to "Go To"

The following code is better form:

while( isValidState() ) {
  execute();
}

bool isValidState() {
  return msg->state != DONE;
}

Advantages

No flag. No goto. No exception. Easy to change. Easy to read. Easy to fix. Additionally the code:

  1. Isolates the knowledge of the loop's workload from the loop itself.
  2. Allows someone maintaining the code to easily extend the functionality.
  3. Allows multiple terminating conditions to be assigned in one place.
  4. Separates the terminating clause from the code to execute.
  5. Is safer for Nuclear Power plants. ;-)

The second point is important. Without knowing how the code works, if someone asked me to make the main loop let other threads (or processes) have some CPU time, two solutions come to mind:

Option #1

Readily insert the pause:

while( isValidState() ) {
  execute();
  sleep();
}

Option #2

Override execute:

void execute() {
  super->execute();
  sleep();
}

This code is simpler (thus easier to read) than a loop with an embedded switch. The isValidState method should only determine if the loop should continue. The workhorse of the method should be abstracted into the execute method, which allows subclasses to override the default behaviour (a difficult task using an embedded switch and goto).

Python Example

Contrast the following answer (to a Python question) that was posted on StackOverflow:

  1. Loop forever.
  2. Ask the user to input their choice.
  3. If the user's input is 'restart', continue looping forever.
  4. Otherwise, stop looping forever.
  5. End.
Code
while True: 
    choice = raw_input('What do you want? ')

    if choice == 'restart':
        continue
    else:
        break

print 'Break!' 

Versus:

  1. Initialize the user's choice.
  2. Loop while the user's choice is the word 'restart'.
  3. Ask the user to input their choice.
  4. End.
Code
choice = 'restart';

while choice == 'restart': 
    choice = raw_input('What do you want? ')

print 'Break!'

Here, while True results in misleading and overly complex code.


A neatish way to do this would be to put this into a function:

int yourfunc() {

    while(true) {

        switch(msg->state) {
        case MSGTYPE: // ... 
            break;
        // ... more stuff ...
        case DONE:
            return; 
        }

    }
}

Optionally (but 'bad practices'): as already suggested you could use a goto, or throw an exception inside the switch.


AFAIK there is no "double break" or similar construct in C++. The closest would be a goto - which, while it has a bad connotation to its name, exists in the language for a reason - as long as it's used carefully and sparingly, it's a viable option.