Is using a 'goto' statement bad?

After doing some reseach on how to break through a secondary loop

while (true) { // Main Loop
   for (int I = 0; I < 15; I++) { // Secondary loop
       // Do Something
       break; // Break main loop?
   }
}

most people recommended to call the 'goto' function
Looking as the following example:

while (true) { // Main Loop
   for (int I = 0; I < 15; I++) { // Secondary Loop
       // Do Something
       goto ContinueOn; // Breaks the main loop
   }
}
ContinueOn:

However; I have often heard that the 'goto' statement is bad practice. The picture below is perfectly illustrating my point: Series found

So

  • How bad is the goto statement really, and why?
  • Is there a more effective way to break the main loop than using the 'goto' statement?

EDIT:

How bad is the goto statement really, and why?

It depends on the exact situation. I can't remember any time where I found it made the code more readable than refactoring. It also depends on your personal view of readability - some people dislike it more than others, as is clear from the other answers. (As a point of interest, it's widely used in generated code - all of the async/await code in C# 5 is based on effectively a lot of gotos).

The problem is that situations where goto tends to be used tend to be the kind of situations where refactoring aids things anyway - whereas goto sticks with a solution which becomes harder to follow as the code gets more complicated.

Is there a more effective way to break the main loop than using the 'goto' statement?

Absolutely. Extract your method out into a separate function:

while (ProcessValues(...))
{
    // Body left deliberately empty
}

...

private bool ProcessValues()
{
   for (int i = 0; i < 15; i++)
   {
       // Do something
       return false;
   }
   return true;
}

I generally prefer doing this over introducing an extra local variable to keep track of "have I finished" - although that will work too, of course.


I'm going to strongly disagree with all of the other answers here. The code you present using goto has nothing wrong with it. There is a reason C# has a goto statement, and it is precisely for these types of scenarios which you describe.

goto simply has a negative stigma because in 1970s and prior people would write horrible, completely unmaintainable code where control flow jumped all over the place because of goto. C#'s goto does not even allow transitioning between methods! Yet there is still this irrational stigma against it.

In my opinion, there is absolutely nothing wrong with using a "modern" goto to break out of an inner loop. The "alternatives" people offer always end up being more complicated and harder to read.

Methods are generally supposed to be reusable. Making a whole separate method for the inner part of a loop, that will only ever get called from that one location, and where the method implementation may end up being at some distant location in the source code, is not an improvement.