"Break;" out of "If" Statement?

Can you break out of an if statement or is it going to cause crashes? I'm starting to acquaint myself with C, but this seems controversial. The first image is from a book on C ("Head First C") and the snippet shows code written by Harvard's CS classes staff. What is actually going on and has it something to do with C standards?

breaks don't break if statements.

On January 15, 1990, AT&T's long-distance telephone system crashed, and 60,000 people lost their phone service. The cause? A developer working on the C code used in the exchanges tried to use a break to break out of an if statement. But breaks don't break out of ifs. Instead, the program skipped an entire section of code and introduced a bug that interrupted 70 million phone calls over nine hours.

for (size = 0; size < HAY_MAX; size++)
{
    // wait for hay until EOF
    printf("\nhaystack[%d] = ", size);
    int straw = GetInt();
    if (straw == INT_MAX)
        break;

    // add hay to stack
    haystack[size] = straw;
}
printf("\n");
8

5 Answers

break interacts solely with the closest enclosing loop or switch, whether it be a for, while or do .. while type. It is frequently referred to as a goto in disguise, as all loops in C can in fact be transformed into a set of conditional gotos:

for (A; B; C) D;
// translates to
A;
goto test;
loop: D;
iter: C;
test: if (B) goto loop;
end:

while (B) D;          // Simply doesn't have A or C
do { D; } while (B);  // Omits initial goto test
continue;             // goto iter;
break;                // goto end;

The difference is, continue and break interact with virtual labels automatically placed by the compiler. This is similar to what return does as you know it will always jump ahead in the program flow. Switches are slightly more complicated, generating arrays of labels and computed gotos, but the way break works with them is similar.

The programming error the notice refers to is misunderstanding break as interacting with an enclosing block rather than an enclosing loop. Consider:

for (A; B; C) {
   D;
   if (E) {
       F;
       if (G) break;   // Incorrectly assumed to break if(E), breaks for()
       H;
   }
   I;
}
J;

Someone thought, given such a piece of code, that G would cause a jump to I, but it jumps to J. The intended function would use if (!G) H; instead.

2

This is actually the conventional use of the break statement. If the break statement wasn't nested in an if block the for loop could only ever execute one time.

MSDN lists this as their example for the break statement.

As already mentioned that, break-statement works only with switches and loops. Here is another way to achieve what is being asked. I am reproducing as nobody else mentioned it. It's just a trick involving the do-while loop.

do {
  // do something
  if (error) {
    break;
  }
  // do something else
  if (error) {
    break;
  }
  // etc..
} while (0);

Though I would prefer the use of goto-statement.

2

I think the question is a little bit fuzzy - for example, it can be interpreted as a question about best practices in programming loops with if inside. So, I'll try to answer this question with this particular interpretation.

If you have if inside a loop, then in most cases you'd like to know how the loop has ended - was it "broken" by the if or was it ended "naturally"? So, your sample code can be modified in this way:

bool intMaxFound = false;
for (size = 0; size < HAY_MAX; size++)
{
  // wait for hay until EOF
  printf("\nhaystack[%d] = ", size);
  int straw = GetInt();
  if (straw == INT_MAX)
     {intMaxFound = true; break;}

  // add hay to stack
  haystack[size] = straw;
}
if (intMaxFound)
{
  // ... broken
}
else
{
  // ... ended naturally
}

The problem with this code is that the if statement is buried inside the loop body, and it takes some effort to locate it and understand what it does. A more clear (even without the break statement) variant will be:

bool intMaxFound = false;
for (size = 0; size < HAY_MAX && !intMaxFound; size++)
{
  // wait for hay until EOF
  printf("\nhaystack[%d] = ", size);
  int straw = GetInt();
  if (straw == INT_MAX)
     {intMaxFound = true; continue;}

  // add hay to stack
  haystack[size] = straw;
}
if (intMaxFound)
{
  // ... broken
}
else
{
  // ... ended naturally
}

In this case you can clearly see (just looking at the loop "header") that this loop can end prematurely. If the loop body is a multi-page text, written by somebody else, then you'd thank its author for saving your time.

UPDATE:

Thanks to SO - it has just suggested the already answered question about crash of the AT&T phone network in 1990. It's about a risky decision of C creators to use a single reserved word break to exit from both loops and switch.

Anyway this interpretation doesn't follow from the sample code in the original question, so I'm leaving my answer as it is.

You could possibly put the if into a foreach a for, a while or a switch like this

Then break and continue statements will be available

foreach ([1] as $i) if ($condition) { // Breakable if
    //some code
    $a = "b";
    // Le break 
    break;
    // code below will not be executed
}
for ($i=0; $i < 1 ; $i++) if ($condition) { 
    //some code
    $a = "b";
    // Le break 
    break;
    // code below will not be executed
}

switch(0){ case 0: if($condition){

   //some code
   $a = "b";
   // Le break 
   break;
   // code below will not be executed

}}



while(!$a&&$a=1) if ($condition) {

   //some code
   $a = "b";
   // Le break 
   break;
   // code below will not be executed

}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Chloe Bennett

Chloe Bennett

Culture, Media & Entertainment Columnist

Chloe Bennett explores the intersection of pop culture, streaming entertainment, digital trends, and contemporary lifestyle. Her weekly commentary reaches thousands of culture enthusiasts.

Share this article
Twitter Facebook Pinterest