views:

258

answers:

7

How can I do this cleanly without gotos?

loop:
  if(condition1){
    something();
  } else if (condition2) {
    somethingDifferent();
  } else {
    mostOfTheWork();
    goto loop;
  }

I'd prefer not to use breaks as well. Furthermore, it is expected to loop several (adv 40) times before doing something else, so the mostOfTheWork part would most likely be as high up as possible, even if just for readability. Thanks in advance.

EDIT: This was posted under the misconception that the compiler optimizer worked poorly with breaks, which, while generally stupid to begin with, I have proven incorrect to myself through experimentation (of performance). On the other hand, thank you for your answers; they have been interesting reads on varying styles.

+9  A: 
bool done = false ;

while( !done ) {
  if(condition1){
    something();
    done = true ;
  } else if (condition2) {
    somethingDifferent();
    done = true ;
  } else {
    mostOfTheWork();
  }
} 
tpdi
Darn. You typed faster, good work. Nice to know that I came up with the same solution though.
Jed Daniels
;) But I'm a slow typist.
tpdi
+2  A: 

Without breaks?

function foo(){
  if(condition1){
    something();
    return;
  } else if (condition2) {
    somethingDifferent();
    return;
  }
  mostOfTheWork();
  foo(); //(Tail recursive for those worried about stack overflows)
}

However, breaks are there for flow control, they are much clearer as to what they do than goto, so I would recommend using them. However in this case I would recommend @John's answer as the correct way to do it.

Yacoby
+1 now explain recursion ;)
Byron Whitlock
to understand recursion yada yada yada...
fireeyedboy
Not all languages will optimize tail calls. This could still cause stack overflow in many languages.
R Samuel Klatchko
@R Samuel Very true.
Yacoby
In this, the tenth year of the 21st century, a "production quality" compiler that does not optimize tail calls is hopelessly brain-dead. The idea has been around for more than three decades: read the "Lambda: the Ultimate ..." series of MIT AI Lab memos.
John R. Strohm
+9  A: 

Clearly, you will break out of the loop if either condition fires.

    while ((!condition1) && (!condition2)) {
      MostOfTheWork();
    }
    if (condition1) {
      something();
    } else if (condition2) {
      somethingDifferent();
    }

So, loop while neither condition has fired, then see which one got you.

Now, someone will scream that I evaluated the conditions more than I needed to. For their benefit, a modified version:

{
  bool t1, t2;
  while ((!(t1 = condition1)) && (!(t2 =condition2))) {
    MostOfTheWork();
  }
  if (t1) {
    something();
  } else if (t2) {
    somethingDifferent();
  }
}
John R. Strohm
+1 I think this is the solution displaying the sharpest observation.
fireeyedboy
John R. Strohm
A: 

Since you weren't specific about a language, some languages have continue, next or skip that you can use in place of that goto.

Forgotten Semicolon
A: 
do
{
  if(condition1){
    something();
  } else if (condition2) {
    somethingDifferent();
  } else {
    mostOfTheWork();
  }
} while (!condition1 && !condition2)
Byron Whitlock
+1  A: 

No gotos or beaks. Cleaniless as always, subjective

 do {
   if ( condition1 )
     something();
   else if( condition2 )
     somethingElse();
   else
     mostOfTheWork();
 } while( !(condition1 || condition2) );

This is of course, incredibly silly. Just use a break.

Logan Capaldo
A: 

You've probably had it drilled into your head by CS professors that it's bad and will wreak havoc in your code. Gotos are actually quite efficient when used properly and purposely. This is why most programming languages haven't dropped it.

In your particular case, the goto is fine because the block of code is small and you can easily see the program flow. You can write spaghetti code with other control structures too, although it's a little harder to do.

Joel Rodgers