C++ best way to break out of nested for loops

Started by
16 comments, last by 21st Century Moose 8 years ago

C++ best way to break out of nested for loops

for a ......

for b .....

if (some_condition)

// break out of both loops

a break will get you out of the inner loop.

but i think only goto will get you out of both, without returning that is.

Norm Barrows

Rockland Software Productions

"Building PC games since 1989"

rocklandsoftware.net

PLAY CAVEMAN NOW!

http://rocklandsoftware.net/beta.php

Advertisement

Put it in the loop statement rather than use break.


for( a = a_init; a != a_end && !condition; a = a_next )
  for( b = b_init; b != b_end && !condition; b = b_next )
    ...

Or break the algorithm out into it's own function and use return.

return always seems cleanest to me.

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


Or break the algorithm out into it's own function and use return.


return always seems cleanest to me.

yeah, that's what i usually do.

but its just a stupid little nested loop to iterate over a collision map and find the first passable node for use as a test goal for the new A* code in Caveman 3.0.

i'll make it a function call with return.

its faster than looking up goto syntax, and cleaner than stuffing it into the for() statement.

some "patterns" never change, eh?

Norm Barrows

Rockland Software Productions

"Building PC games since 1989"

rocklandsoftware.net

PLAY CAVEMAN NOW!

http://rocklandsoftware.net/beta.php

some "patterns" never change, eh?

We get new tools though :)
void test()
{
  printf( "start\n" );
  for( int x=0; x!=10; ++x )
    for( int y=0; y!=10; ++y )
      if( x == y && x == 5 )
        goto double_break;
      else
        printf( "%d, %d\n", x, y );
  double_break:
  printf( "end\n" );
}
In 2016 can be written as:
void test()
{
  printf( "start\n" );
  [](){
  for( int x=0; x!=10; ++x )
    for( int y=0; y!=10; ++y )
      if( x == y && x == 5 )
        return;
      else
        printf( "%d, %d\n", x, y );
  }();
  printf( "end\n" );
}


In 2016 can be written as:

less keystrokes, but lower on read-ability too.

just an observation.

Norm Barrows

Rockland Software Productions

"Building PC games since 1989"

rocklandsoftware.net

PLAY CAVEMAN NOW!

http://rocklandsoftware.net/beta.php

Lol yeah you'd never write either of those two bits of code, hopefully :lol:

The lambda syntax comes in handy when you want to reuse a bit of code, but don't want to bother actually breaking it out into it's own independent function, yet. e.g.


void test()
{
  int sum = 0;
  auto SumArray = [&](int* data, int size){
    for( int i=0; i!=size; ++i )
      sum += data[i];
  };
  for( int widgetIdx=0; widgetIdx != numWidgets; ++widgetIdx )
    SumArray( widgets[widgetIdx].data, widgets[widgetIdx].size );
  SumArray( specialWidget.data, specialWidget.size );
  printf( "%d\n", sum );
}

which is shorthand for:


void test()
{
  int sum = 0;
  struct _ { _(int& sum):sum(sum){}int& sum;
    void operator()(int* data, int size){
      for( int i=0; i!=size; ++i )
        sum += data[i];
    };
  }SumArray(sum);
  for( int widgetIdx=0; widgetIdx != numWidgets; ++widgetIdx )
    SumArray( widgets[widgetIdx].data, widgets[widgetIdx].size );
  SumArray( specialWidget.data, specialWidget.size );
  printf( "%d\n", sum );
}

or the more obvious, actually breaking it out into it's own separate function:


namespace { void SumArray(int* data, int size, int& sum){
  for( int i=0; i!=size; ++i )
    sum += data[i];
};}
void test()
{
  int sum = 0;
  for( int widgetIdx=0; widgetIdx != numWidgets; ++widgetIdx )
    SumArray( widgets[widgetIdx].data, widgets[widgetIdx].size, sum );
  SumArray( specialWidget.data, specialWidget.size, sum );
  printf( "%d\n", sum );
}

There is precisely nothing wrong with using a goto here, so use a goto.

People should be taught that the way you break out of a loop is with a goto to the line after the loop, and you can skip to the next iteration of the loop with a goto to the last line of the loop block. These usages of goto are so common that the C language introduced special names for them: `break' and `continue'. Since they didn't introduce a special name for the goto that breaks out of nested loops, you still need to write a goto and a label, but what's going on is exactly the same thing.

some "patterns" never change, eh?

We get new tools though :)

void test()
{
  printf( "start\n" );
  for( int x=0; x!=10; ++x )
    for( int y=0; y!=10; ++y )
      if( x == y && x == 5 )
        goto double_break;
      else
        printf( "%d, %d\n", x, y );
  double_break:
  printf( "end\n" );
}
In 2016 can be written as:

void test()
{
  printf( "start\n" );
  [](){
  for( int x=0; x!=10; ++x )
    for( int y=0; y!=10; ++y )
      if( x == y && x == 5 )
        return;
      else
        printf( "%d, %d\n", x, y );
  }();
  printf( "end\n" );
}

Did not realize you could invoke the lambda at its definition.

"its faster than looking up goto syntax"

If you've ever written a goto, how could you possibly need to look up the syntax?

I'd be looking up the break syntax if anything, to see if C++ features labeled breaks yet.

I think they mentioned something about a multi-break at the con, but I can't remember clearly.
void hurrrrrrrr() {__asm sub [ebp+4],5;}

There are ten kinds of people in this world: those who understand binary and those who don't.

This topic is closed to new replies.

Advertisement