5

I have really simple code where I use break inside inner loop:

for (int it=0; it<5; it++) {
    for (int it2=0; it2<5; it2++) {
        if (it2==2) 
            break; //break here not it2, but it loop
        NSLog(@"it=%d it2=%d", it, it2);
    }
}

I receive an output:

it=0 it2=0, it=0 it2=1, 
it=1 it2=0, it=1 it2=1, 
it=2 it2=0, it=2 it2=1,
it=3 it2=0, it=3 it2=1,
it=4 it2=0, it=4 it2=1

I know in some programic languages there is possibility to determine on which loop break statement should affect. Is it possible to call break to stop outer loop (for with it variable)?

Szu
  • 2,254
  • 1
  • 21
  • 37
  • In c or c++, no. break used only for current loop – A Lan Apr 09 '14 at 12:41
  • 2
    In C you cannot do it with a direct instruction (except `goto` label), but you can break from the 1st loop and set a flag to break the 2nd – n0p Apr 09 '14 at 12:41
  • For your question the way you ask it, you have two options: `goto` or a function. The more interesting question would be: what is your actual problem (the example you provide looks contrived), and in which language are you trying to solve it? – Björn Pollex Apr 09 '14 at 13:09
  • I got such problem in objective-c but every when it appears I find good solution to avoid two for loops. – Szu Apr 09 '14 at 13:24

6 Answers6

12

If you really want to do this, then bite the bullet and use goto.

for (int it=0; it<5; it++) {
    for (int it2=0; it2<5; it2++) {
        if (it2==2) 
            goto end_outer_loop;
        NSLog(@"it=%d it2=%d", it, it2);
    }
}

end_outer_loop:

// more stuff here.

This is a legitimate goto (most gotos in the downward direction are). In fact break is a special kind of "approved" goto, and because C is a minimal language you have to use an explicit goto in complex cases.

However as many people here have pointed out, it's better if you can use return. You should not contort your program just to avoid goto, but in most cases it is a clue that your function is become too complex and should therefore be broken up.

Adrian Ratnapala
  • 5,485
  • 2
  • 29
  • 39
  • 1
    `goto` shouldn't be used here. This is a text book use case for a function. – Björn Pollex Apr 09 '14 at 12:40
  • 1
    Help! I am having a nasty flashback to the 1970s – ravenspoint Apr 09 '14 at 12:43
  • 10
    It's good to break things into smaller functions. But you shouldn't do that *just so you can avoid a goto*. That really depends on whether the loop is strongly related to the calculation or not. This is why other languages have Special language Features for this (loop labels, integer argument for break etc). – Adrian Ratnapala Apr 09 '14 at 12:44
  • 1
    I'd also agree that for this case a `goto` is perfectly fine. Especially since the label will be very close to the `goto`. – lethal-guitar Apr 09 '14 at 12:46
  • 2
    When people have asked me for legit uses of `goto`, this is the one and only example I can cite that is in actual practical common use. I don't know why people are so averse to `goto` but totally fine with `switch` which, because of its scoping, carries the same consequences. – tenfour Apr 09 '14 at 12:48
  • 2
    @tenfour exactly this. It's like everybody stops thinking just because they were told "goto is teh evul!" someday. – lethal-guitar Apr 09 '14 at 12:49
  • Thank you @AdrianRatnapala for your answer. I almost forgot that goto ever exists and now i see in some cases it's usefull. – Szu Apr 09 '14 at 12:54
  • @tenfour, the other cases I know of are `switch`-inside-a-loop and (sometimes) error exits. But error exits are dangerous if your compiler (e.g. MSVC++) doesn't warn you about potentially undefined variables. – Adrian Ratnapala Apr 09 '14 at 12:55
  • 2
    I agree that this is one of the few cases that goto SHOULD be used. Using a function feels like forcing a different design just for the sake of not using a goto. – Veritas Apr 09 '14 at 12:56
  • 1
    +1 but OP should be warned that `goto`s are indeed considered harmful to one's reputation because of so much mindless stigma around them – Alsk Apr 09 '14 at 13:01
  • @Alsk: but I only got two downvotes for this. Fingers crossed. – Adrian Ratnapala Apr 09 '14 at 13:05
  • 1
    Worth noting that this example is even the main feature of the [MSDN page on `goto`](http://msdn.microsoft.com/en-us/library/b34dt9cd.aspx) – tenfour Apr 09 '14 at 13:35
6

You can use a bool flag to serve the purpose, something like this:

bool flag = false;
for (int it=0; it<5; it++) {
    for (int it2=0; it2<5; it2++) {
        if (it2==2) { flag=true; break; }
        NSLog(@"it=%d it2=%d", it, it2);
    }
    if(flag) {break;}
}

This method shall be used only if you cannot use the return method as specified by others. return improves code-readability. This is just a workaround.

The goto method is also a valid one, but it is always advised not to use goto, just because it breaks the control flow and can cause hours of debugging if the code is large enough!

CinCout
  • 9,486
  • 12
  • 49
  • 67
  • 3
    In my eyes, this is less readable and clear than using a `goto`. – lethal-guitar Apr 09 '14 at 12:47
  • I got the same idea but if statement is unnecessary. You can add condition in for statement – Szu Apr 09 '14 at 12:49
  • @Szu I agree to your proposal! – CinCout Apr 09 '14 at 12:59
  • 1
    These flag variables are only mildly annoying because they are used locally; but they are a sign of the "lets add a state variable disease". And hacked-in state variables are the worst cause I know of errors and hard-to-understand code. – Adrian Ratnapala Apr 09 '14 at 13:04
  • 1
    @gargankit where do you get the idea that `goto` is so powerful? You cannot `goto` outside of the current function... – tenfour Apr 09 '14 at 13:37
1

In C/C++, you really don't have something like that. There are clearly some answers already, such as use goto or something. Personally, I don't like gotos and thing they kinda lead to some sloppy code (IMO).

To me you have two good options here.

  1. Write the loop conditions so that they include the exit condition in both. This is the way I would personally go since I don't like the idea of using break or something in a loop, unless I absolutely have to. I just think it makes for a little cleaner product is all, and it's what I was taught.

  2. If you do decide to keep the break, then instead of doing a single-line if() to control it, break it into two parts and create a "break flag" that will be set if the break condition is met. From there, either place an additional condition in your outer loop to exit if that flag is set, or have another if() inside the outer loop (but not inside the inner loop) that will break if that flag is set.

Hope this helps.

Josh Braun
  • 490
  • 2
  • 16
0

You should wrap your loops in a function and then use return to return from that function.

Björn Pollex
  • 75,346
  • 28
  • 201
  • 283
  • 4
    That's a classic case of forcing a design because of language aspects. It should be the other way around – SomeWittyUsername Apr 09 '14 at 12:46
  • 1
    I agree that in some cases this _might_ be the way to do it. It is hard to give a definite answer without knowing the OPs actual problem. I'd argue that for almost all use-cases wrapping the iteration into a function implementing an algorithm results in a cleaner solution than using `goto`. – Björn Pollex Apr 09 '14 at 13:07
  • A good heuristic is to ask whether you can come up with a good name for that function. Which is the same asking whether that loop does some distinct, identifiable thing. If such a name exists, then it makes your code self-commenting. If no such name exists, then then the in\lined text will be easier to read because it saves the reader from having to penetrate the extra layer of indirection. – Adrian Ratnapala Feb 28 '17 at 02:39
0

In programming using goto statement makes the logic of the program complex and tangled. In modern programming, goto statement is considered a harmful construct and a bad programming practice.

You can use it as a function and when condition occurs function exits

int loop(int it,int it2)
{
  for (int it=0; it<5; it++) {
    for (int it2=0; it2<5; it2++) {
        if (it2==2) return 0; //function returns here
        NSLog(@"it=%d it2=%d", it, it2);
    }
  }
  return 1;
}
Sorcrer
  • 1,634
  • 1
  • 14
  • 27
  • 3
    Breaking out of loops is one case where `goto` is considered perfectly fine. And there won't be much complexity added, as the label is really close to the jump. – lethal-guitar Apr 09 '14 at 12:47
  • I agree goto is useful , but from a professional programmers point of view it is considered to be a bad habit using goto statements. Because this could create ambiguity while reading code by others while using in complex programs. In simple ones it's ok . But for his knowledge I let him knew that it's a bad habit to use goto. – Sorcrer Apr 09 '14 at 12:54
  • 1
    It is viewed as a bad habit everywhere except from this case. Hell, even MISRA C++ allows this. I don't see how wrapping the loops in a function is any better, it simply reduces readability in my opinion and doesn't offer any advantages since return also breaks the control flow. – Veritas Apr 09 '14 at 15:20
  • 1
    @hariprasad do you, as a professional programmer, use exceptions, or `switch` statements? All these can create ambiguity for others reading the code when *misused* in complex programs. It always depends on how a feature is used, and in this specific use case `goto` will certainly *not* be seen as bad habit. – lethal-guitar Apr 10 '14 at 08:48
-1

Unfortunately, c++ does not have that kind of break. A possibility considered abomination is using goto. There are two acceptable solution:

  1. Put this code in a separate function, and use return

  2. Use a boolean flag

    bool stopFlag = false; for (int it=0; it<5 && !stopFlag; it++) { for (int it2=0; it2<5; it2++) { if (whatever) { stopFlag=true; break; } }

Ophir Gvirtzer
  • 604
  • 4
  • 8
  • This is one of the few cases that using goto is considered the better solution. – Veritas Apr 09 '14 at 12:57
  • Veritas, I think otherwise, since in this case there are two clean alternatives. But this is a matter of taste. – Ophir Gvirtzer Apr 09 '14 at 13:08
  • Sure there are alternatives but goto is the cleaner choice. Return is really a goto in disguise and it also breaks the control flow so it doesn't offer any advantages other than providing extra work for the programmer. – Veritas Apr 09 '14 at 15:26
  • Big unlike to whoever down-voted me for having different taste than his. – Ophir Gvirtzer Apr 10 '14 at 07:53