0

In a situation like the loop below, what are the ways other than goto to get out of the nested loop at once?

#include<stdio.h>

int main(void)
{
    int  i,j,k ;

    for(i=1;i<=3;i++)
    {
        for(j=1;j<=3;j++)
        {
            for(k=1;k<=3;k++)
            {
                if(i==3&&j==3&&k==3)
                    goto out ;
                else
                    printf("%d%d%d\n",i,j,k) ;
            }
        }
    }
out :
    printf("Out of the loop at last!") ;
}
Robert Harvey
  • 178,213
  • 47
  • 333
  • 501
Thokchom
  • 1,602
  • 3
  • 17
  • 32

4 Answers4

5

goto is not bad when used reasonably.

If you need to exit from many loops at once, it often means that your code should be redesigned. Such a 'cascade break is something like emergency exit. Maybe it's the right time to move your code into a separate function and use return there.

nullptr
  • 11,008
  • 1
  • 23
  • 18
2

One solution might be an additional condition.

#include<stdio.h>

int main(void)
{
    int  i,j,k ;
    int abort = 0;
    for(i=1; i<=3 && !abort; i++)
    {
        for(j=1; j<=3 && !abort; j++)
        {
            for(k=1; k<=3 && !abort; k++)
            {
                if(i==3&&j==3&&k==3)
                    abort = 0;
                else
                    printf("%d%d%d\n",i,j,k) ;
            }
        }
    }
    printf("Out of the loop at last!") ;
}
DrummerB
  • 39,814
  • 12
  • 105
  • 142
1

Forget those "sources" - there ARE valid reasons for goto. Besides, break is not quite different. However, if you really want, you could move the loops into their own subfunction and leave this with return.

JeffRSon
  • 10,404
  • 4
  • 26
  • 51
1

This is one of the few cases where using a goto would be acceptable, although it would be better to re-think that loop.

The main problem with goto is that it can destroy the ability to debug code by simple inspection.

Consider the following code snippet:

i = 10;
label: printf("%d\n", i);

What value gets printed for i? Does the line i = 10; even get executed? I can't know until I account for every instance of goto label; in the function, meaning I have to manually trace the execution path. Depending on the size of the function, this can go from a minor annoyance to a major pain in the ass. Bonus points if there are additional gotos in the same function.

If you follow a few simple rules, it isn't so bad: branch forward only, don't branch into a control structure (if, while, for, etc.), don't branch over declarations or initializations, etc. Basically treat it like a break statement. But honestly, if you can avoid using it, do so.

John Bode
  • 119,563
  • 19
  • 122
  • 198