Breaking out of a nested loop

Started by
50 comments, last by ExErvus 7 years, 10 months ago

If you want to see a real masterpiece, look at page 3 or 4 of the comments here https://derpibooru.org/883523


What the...blink.png That's a real site?

Advertisement

https://derpibooru.org/883523


Not a site i ever expected would be linked to on gamedev tongue.png

Not a site I ever expected would exist outside my nightmares.

Why is my thread now in coding horrors biggrin.png What have you people done to my beautiful thread?

"I would try to find halo source code by bungie best fps engine ever created, u see why call of duty loses speed due to its detail." -- GettingNifty

Why is my thread now in coding horrors biggrin.png What have you people done to my beautiful thread?


We fixed it for you and made it better!! 'Welcome!

In C/C++ the "cleanest" code for breaking from an inner loop:

...

I feel like we need a new keyword. Perhaps a break_harder or combo_break keyword to break from 2 loops or something?

If you hate 'goto' so much, why not use an extra variable instead?


int i, j;
bool done = false;
for(i = 0; i < 10; i++) {
    for(j = 0; j < 10; j++) {
        if(i - 1 == j + 1) {
            done = true;
            break;
        }
    }
    if (done) break;
}

Folding the inner loop into a function is alos a good alternative, imho.

If the compiler does not constant fold everything together, it will replace everything with jumps/gotos anyway.tongue.png

If you hate 'goto' so much, why not use an extra variable instead?

This gets real ugly real fast once you go beyond 2 levels of nesting though. Which, now that this topic is in Coding Horrors, is probably the point...

Direct3D has need of instancing, but we do not. We have plenty of glVertexAttrib calls.

If you hate 'goto' so much, why not use an extra variable instead?

This gets real ugly real fast once you go beyond 2 levels of nesting though.

No worries! I got this!!!


int i, j;
bool done = false;
for(i = 0; !(i >= 10 || done); i++) {
    for(j = 0; !(j >= 10 || done); j++) {
        if(i - 1 == j + 1) {
            done = true;
        }
    }
}

All these solutions use pretty awful coding practices.

Here's the recommended way:


#include "assert.h"
#include "setjmp.h"
#include "string.h"

#define BUFFER(y) y ## _buf

#define TRUE 0
#define FALSE 1
#define If ) {

int Condition(int *var = TRUE, int compare = TRUE)
{
    if((!compare) == FALSE)
    {
        *var = 0;
        return TRUE;
    }
    else
    {
        return (*var >= compare)? TRUE : FALSE;
    }

    return (TRUE == FALSE) == TRUE;
}

BUFFER(jmp) can;
bool FAILED = false;

int InnerLoop(int q)
{
    //Don't forget to comment your code.
    for(int j = 0; Condition(&j,10) == FALSE; j++)
    {
        if(q - 1 == j + 1)
        {
            throw Condition;
        }
    }
}

#define VISTA X.X
#define    ME ...
#define    XP .X.
#define    U(xXx)  auto &Func = xXx; BUFFER(jmp) & \
  InnerLoop = Func;
//OuterLoop = Func; No longer neccesary.

bool OuterLoop()
{
    FAILED = FALSE;
    
    try { for(int i = 0; (Condition(&i,10) != TRUE); i += FALSE)
    {
        InnerLoop(i);
    }}
    catch(ME If U(can)
    {
        longjmp(InnerLoop, (FALSE == TRUE));
        printf("An error occured.");
        FAILED = TRUE;
    }}

    return true;
}

int main()
{
    retry:
    if(FAILED)
    {
        return TRUE;
    }
    
    if(setjmp(can))
    {
        goto retry;
    }

    assert(OuterLoop() && "Make sure this always returns successfully.");
    return FALSE;
}

This works fine (with the same behavior as the other examples in this thread), and doesn't trigger the assert(), so clearly it's stable for mission-critical applications like self-driving cars, the Mars rover, and pacemakers. Coming soon to a hospital near you - ask your doctor about ServaCode today!


Here's the recommended way:

I see you're supporting Vista, ME, and XP, but not Mac OS X or Linux. Is there a cross-platform version of your solution?

Stephen M. Webb
Professional Free Software Developer

This topic is closed to new replies.

Advertisement