gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

Coding > A simple one.

#60172 - lewisrevill - Mon Nov 07, 2005 9:22 pm

I know alot of people are guna hate me for asking this cos it seems like no one likes using it (can someone tell me why) But can some one tell how to use the 'goto' command in 'C' language and give an example. Thank you!

#60177 - DekuTree64 - Mon Nov 07, 2005 9:37 pm

Code:
void InfiniteLoop()
{
thisIsALabelThatYouCanGoto:
    goto thisIsALabelThatYouCanGoto;
}

I don't use it very often just because I don't need it very often. Almost always there's another way you can get the same effect using if statements or breaking up functions, but in the right situation it can make things a lot simpler.
_________________
___________
The best optimization is to do nothing at all.
Therefore a fully optimized program doesn't exist.
-Deku

#60181 - tepples - Mon Nov 07, 2005 10:02 pm

In general, C's goto is useful where you would use C++'s exceptions.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#60182 - Codax - Mon Nov 07, 2005 10:11 pm

I once thought a lot like you when it came to GOTO statements. I started with a huge BASIC background in which everything good was done with GOTO. But as any BASIC programmer will tell you. A million GOTOs got hella confusing.

When it comes to Object Oriented (read modern) Programming Techniques GOTOs are not only confusing, but hard to maintain. Everything GOTOs once did have been replaced with better alternatives

FOR, WHILE, DO-WHILE, and Function calls are much easier to maintain, and reuse. They also help prevent useless/redundant labeling and naming. (ie "Where the hell is does 'GOTO a' actually goto?") By using function calls you can have coding short cuts that were very difficult to do with GOTO

ie. Take adding two numbers.....ANY two numbers (even stored in vars)
Code:

void int AddTheseNumbers(int a, int b)
{  return a+b; }


While this may seem trivial, try to add a bunch of numbers that are held in variables or structures. Now try to do it a bunch of times using only GOTO statements. Hell try it doing it mutliple times in one statement. I don't want to even imagine all the code that would have to be written.

Hope this clears things up a little.
_________________
Codax
Dragon's Den Unlimited
http://www.DrgnDen.com

#60185 - poslundc - Mon Nov 07, 2005 11:02 pm

tepples wrote:
In general, C's goto is useful where you would use C++'s exceptions.


Is this the try/throw/catch constructs you're referring to?

I've never really seen an exception-handling pattern implemented with gotos that really justified their use to me. In practice, they almost always bail out of the program anyway, so they might as well be achieved with a function call or ASSERT-style construct rather than a line jump, which obfuscates the code.

(Not saying that such a thing couldn't exist... only that I've yet to see it.)

Dan.

#60187 - Miked0801 - Mon Nov 07, 2005 11:09 pm

Agreed - there are only 2 times I've somewhat condoned a goto to live in my code base. One was in some extremely tight ARM code that needed to match the underlying assembly very closely and the other was in a deep while(){ while() { switch() - if major error has occured, goto to end of function }}}} type contruct - and even here, refactoring would have been a better solution.

#60194 - LOst? - Mon Nov 07, 2005 11:53 pm

I often end up using goto when break won't work, like in this situation:
Code:

for (int i = 0; i < 16; i++)
{

for (int j = 0; j < 16; j++)
{
 if (data [j + i] == EOF)
  goto found_end;
}

}

found_end:;

_________________
Exceptions are fun

#60203 - gauauu - Tue Nov 08, 2005 1:37 am

Just out of curiosity, thinking more about tepples' idea of using a goto for exception-style handling, can you use a goto to leave the function you are in and jump into the middle of a different function?

If so, what happens to your stack?

#60208 - tepples - Tue Nov 08, 2005 2:11 am

gauauu wrote:
Just out of curiosity, thinking more about tepples' idea of using a goto for exception-style handling

Clarification: I was thinking of using this more for try/catch side than the throw side.

Quote:
can you use a goto to leave the function you are in and jump into the middle of a different function?

Look for setjmp().
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#60213 - keldon - Tue Nov 08, 2005 2:46 am

Code:
for (int i = 0; i < 16; i++){
   for (int j = 0; j < 16; j++) {
      if (data [j + i] == EOF)
      goto found_end;
   }

}


java removes the goto statement, where your code would be replaced with
Code:
breakLabel: for ( int i = 0; i < 16; i++ ) {
   for (int j = 0; j < 16; j++) {
      if (data [j + i] == EOF) break breakLabel;
   }
}


which is equivalent to the C code of:
Code:
innerLoop = TRUE;
for ( int i = 0; i < 16 && innerLoop; i++ ) {
   for (int j = 0; j < 16; j++) {
      if (data [j + i] == EOF) {
         innerLoop = FALSE;
         break;
      }
   }
}

#60239 - sgeos - Tue Nov 08, 2005 10:13 am

lewisrevill wrote:
I know alot of people are guna hate me for asking this cos it seems like no one likes using it (can someone tell me why) But can some one tell how to use the 'goto' command in 'C' language and give an example. Thank you!


This is basic usage:
Code:
someGotoFunction()
{
   // Code Here
   goto myLabel;

   // More Code Here

   myLabel:
   // Even More Code Here
}


People don't like gotos because there are almost always better alternatives- loops, function calls and such. (See other posts.) When abused, you can use gotos to do horrible, horrible things- like jumping through scope:
Code:
someReallyBadFunction()
{
   // code
   if (aCondition)
      goto aLabel;

   // more code
   for (...; ...; ...)
   {
      while (...)
      {
         for (...; ...; ...)
         {
            // code
            bLabel:
            // more code
         }
         aLabel:
         // even more code

         if (bCondition)
            goto bLabel;
         // yet even more code
      }
      // more code
      // this function really needs to be refactored =)
   }
}

What in the world am I trying to do?! When does one ever need to do something like this? The answer is never. Nobody will be able to read your code. If you ever use gotos, don't jump into loops and don't jump backwards. Ever.

The only "proper" use of gotos I've heard of is the following:
Code:
someFunction()
{
   if (ERROR == aInit())
      goto aLabel;
   for (;;)
   {
      if (ERROR == bInit())
         goto bLabel;
      for (;;)
      {
         if (ERROR == cInit())
            goto cLabel;
         for (;;)
         {
         }
      }
   }

   // Do not execut deepFuntion on ERROR
   deepFunction();

   // uninitialize in reverse order
   cLabel:
      cUnInit();
   bLabel:
      bUnInit();
   aLabel:
      aUnInit();
}

Breaking out of nested loops. I've never had to do it. Anything that can be done with gotos can be done without them (the above can be done with condition flags). In the end, if gotos simplify things, you might consider using them. Keep in mind, however, that gotos are considered evil. Even if you use them in the rare case that actually does simplify things, you might be looking for a new job. =)

-Brendan

#60320 - LOst? - Wed Nov 09, 2005 4:53 am

LOst? wrote:
I often end up using goto when break won't work, like in this situation:
Code:

for (int i = 0; i < 16; i++)
{

for (int j = 0; j < 16; j++)
{
 if (data [j + i] == EOF)
  goto found_end;
}

}

found_end:;


Question: Is it better for me to use...
Code:

 if (data [j + i] == EOF)
 {
   j = 16;
   i = 16;
 }

...rather than the goto statement?
_________________
Exceptions are fun

#60337 - poslundc - Wed Nov 09, 2005 7:07 am

LOst? wrote:
Question: Is it better for me to use...
Code:

 if (data [j + i] == EOF)
 {
   j = 16;
   i = 16;
 }

...rather than the goto statement?


That would obfuscate your code, and make its termination conditions unclear. If the range of the outer variable ever has to change, or the loop condition changes, or you change it from incrementing to decrementing, etc. you've opened up a hole for bugs to creep in.

When choosing between similar coding options, always favour the one that more closely represents the idea of the algorithm.

Assigning the termination value to your outer variable is a backhanded way of breaking out of the loop. Use the method keldon describes above instead, which I typically expand to make even more obvious:

Code:
bool     bReachedEnd = false;

for (int i = 0; i < 16; i++)
{
     for (int j = 0; j < 16; j++)
     {
          if (data[j + i] == EOF)
          {
               bReachedEnd = true;
               break;
          }
     }

     if (bReachedEnd)
     {
          break;
     }
}


This code is crystal-clear as to what is happening, and won't break if you need to change your outer loop.

A goto would compile to slightly more efficient code. But you are not going to gain any overall performance by using it here, unless it's for code that needs to be very close to the machine representation, such as code being compiled as ARM code and being placed in fast RAM.

Dan.

#60349 - sgeos - Wed Nov 09, 2005 1:03 pm

poslundc wrote:
A goto would compile to slightly more efficient code.

In the above case. Keep in mind that compilers usually can't optimize code that contains gotos.

-Brendan

#60355 - LOst? - Wed Nov 09, 2005 3:46 pm

Thank you poslundc. I will use that technique in the future.
_________________
Exceptions are fun