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

Viewed 147689

I'm writing some code that looks like this:

while(true) {
    switch(msg->state) {
    case MSGTYPE: // ... 
        break;
    // ... more stuff ...
    case DONE:
        break; // **HERE, I want to break out of the loop itself**
    }
}

Is there any direct way to do that?

I know I can use a flag, and break from the loop by putting a conditional break just after the switch. I just want to know if C++ has some construct for this already.

20 Answers

Because the switch uses the break to break out from the switch (not from the while(1)), it needs the goto-statement:

while(1) {
    switch (*p) {
      case ' ':
        p++;
        break;
      case '\n':
        p++; *s=p; return(i);
      case '\0':
        *s=p; return(i);
      default:
        token[i]=p;
        i++;
        p++;
        goto ex1;
    };
  };
  ex1:

I can't add multiple case to same line like:

case ' ','\t':

it would be

case ' ': case '\t':

That's why maybe the break used here...

It looks the most frequent cases should be placed at the top of the list to make the program run faster. It may not have parallel execution for searching the different cases.

It is possible that the standard c then has missing some methods about this switching: https://blog.hackajob.co/better-c-switch-statements-for-a-range-of-values/ => allows you to use the <, >, <=, and >= operators in a switch expression

I was thinking that it should be (if c-language syntax changed) like:

switch (c) {
  case >= 5:
     ... op1
  endcase;
  case == 1:
  case == 3:
     ... op2
  endcase;
  default:
    ...
};

where op2 is executed when c is equal to 1 or 3 and when c is larger than or equal to 5 op1 is executed. Because comparison for equal or larger/smaller than would occur easily in similar manner.

  while(1) {
    switch (c) {
      case >= 2:
         ... op1
      case <= 5:
         ... op2
      break;
      default:
        ...
    };
  };

this case op1 is executed for c larger than 2 and op2 executed for 2<=c<=5 and break exits it from while-loop.

The break keyword in C++ only terminates the most-nested enclosing iteration or switch statement. Thus, you couldn't break out of the while (true) loop directly within the switch statement; however you could use the following code, which I think is an excellent pattern for this type of problem:

for (; msg->state != DONE; msg = next_message()) {
    switch (msg->state) {
    case MSGTYPE:
        //...
        break;

    //...
    }
}

If you needed to do something when msg->state equals DONE (such as run a cleanup routine), then place that code immediately after the for loop; i.e. if you currently have:

while (true) {
    switch (msg->state) {
    case MSGTYPE:
        //... 
        break;

    //...

    case DONE:
        do_cleanup();
        break;
    }

    if (msg->state == DONE)
        break;

    msg = next_message();
}

Then use instead:

for (; msg->state != DONE; msg = next_message()) {
    switch (msg->state) {
    case MSGTYPE:
        //...
        break;

    //...
    }
}

assert(msg->state == DONE);
do_cleanup();
Related