   Avoiding using a "goto"
  A question for those who say "never use goto": What would you do in this situation?I have 2 boolean conditions a and b, and three functions A, B, C. If a is true, I want to execute A. If b is true, execute B. If neither, execute C. C will do some work, then set either a or b to true, in which case I again want to execute A or B respectively. My current solution is:int foo(void){retry:    if(a)   return A();    if(b)   return B();    C();    goto retry;}If I wanted to avoid "goto" here, what should I do? I guess the only construct which would allow me to jump backwards like this would be a loop, but semantically this function is not a loop - in the (highly likely) case that a or b is true, it will exit very quickly.Note also that C is a heavy function and "foo" is called very often - so placing the call to C at the top of the function, in order to be sure that a or b is true before doing any tests, kills my performance.   
  ...It'll all get compiled down into assembler where there's tons of goto's, so doesn't really matter.They should only be avoided for good coding practice (less confusing for others to read).To answer your Q though; for this problem, I would make the function call itself.return foo();instead ofgoto retry;   ;int foo(void){    while(true)    {   if(a)  return A();    if(b)  return B();   C();    }}How about that ? (I assume that somehow C() is able to modify either conditions a and/or b.Nonetheless I would neither agree with people saying "never use goto" nor with people saying "never use xxxxx" or "always use xxxxx". because one size doesn't fit all...Edit: Quote:Original post by Daedalus AITo answer your Q though; for this problem, I would make the function call itself.return foo();instead ofgoto retry;Noooo ! :)If you have the function calling itself you may get some overflow very quickly depending on the situation. (What if for example foo is a render loop, "a" is "the user wants to quit" and "b" is "an error occured", and C() is "render" ?   ;int foo(void){    while ( true )    {   if(a)  return A();   if(b)  return B();   C();    } }P.S. Grrrrrr .....   ;  You're all making it much too complicated. Rearrange: Do the work that makes sure either a or b is set first, and then handle the one that is set.int foo(void) {  while (!(a || b)) { C(); } // could use 'if', if your description is accurate  return a ? A() : B();};Quote:Original post by ZahlmanYou're all making it much too complicated. Rearrange: Do the work that makes sure either a or b is set first, and then handle the one that is set.int foo(void) {  while (!(a || b)) { C(); } // could use 'if', if your description is accurate  return a ? A() : B();}Personally, I don't like that rewrite. It suggests that the loop-until is separate functionality from the decision of what to return, and also implies that a has something to do with B(). Of course, those things might be true, but given how the original code snippet looked it seems unlikely.   ;Quote:How to write unmaintainable code - Misc techniques #2:2 - Foiling DebuggersA very simple way to confound people trying to understand your code by tracing it with a line debugger, is to make the lines long. In particular, put the then clause on the same line as the if. They can't place breakpoints. They can't tell which branch of an if was taken. :)Plua, "a == !b" is not necessatily always true, and if youd want to add a third condition, then you'd have to rewrite it all.   ;Quote:Original post by janta and Red Antwhile(true)...The thing I don't like about these is that on first glance, they appear to be a loop, which could last for several iterations. This is not the general behaviour of this function - most of the time, it exits quickly.Quote:Original post by ZahlmanRearrange: Do the work that makes sure either a or b is set first, and then handle the one that is set.As I said, that is not an option - function C is too heavy. It must only be called when necessary. Just to test, however, I tried the rearrange - my entire application performance dropped by over 25%.I think the thing to do though, is to notice that C will always set one of a or b to true, so this is not really a loop at all. Thus my dislike of the "while(1)" solution, but on a closer look, the goto probably looks that way as well. I guess I'd be best off with:int foo(void){    if(a)   return A();    if(b)   return B();    C();    if(a)   return A();    if(b)   return B();    return something_has_gone_horribly_wrong;}possibly putting the repeated part into a separate function/macro.   ;Quote:Original post by bakery2k1As I said, that is not an option - function C is too heavy. It must only be called when necessary. Just to test, however, I tried the rearrange - my entire application performance dropped by over 25%.Huh?  Zahlman's function has the exact same characteristics as your original code.  It only calls C if neither a nor b are true, same as your original code.  Visual C++ 8.0 even produces exactly the same assembly code for the two snippets (with full optimizations).Σnigma   ;  I hope your just removed the parameters while posting the code. It seems that C() is modifying a and b because they are global vars? I suggest passing the variables as pointers to foo(), C() and removing their global scope. int foo(bool *a, bool *b, bool *c){   int retVal=0;   if(a==true || b==true){ retVal = ProcessAandB(a,b);    }else{C(a,b);if(a==false && b==false){    //Error, a and b are still both false}    retVal = ProcessAandB(a,b);   }   return retVal;}int ProcessAandB(bool a, bool b){   if(a==true){return A();   }    if (b==true){return B();   }   return -1; //this should never execute}