2

I have been given an assignment in my CS class to come up with a situation when it would be a good idea to use a goto statement and write a program for it. It can be any situation (though I have to write the program in 3 days) and so far I haven't thought of anything that couldn't easily be solved either with recursion or iteration. The only thing that I thought of was Towers of Hanoi, but that can be done in only a few lines with recursion. Do you have any suggestions? Thank you for your help.

EDIT: It has to be the actual goto statement, not other statements that serve the same purpose. For example, the user who answered by suggesting switch, raise, throw, etc, don't work for the assignment.

  • You're missing the point. You can't think of a use for a `goto` because these other statements replace it with something more controlled. Instead of a `raise`, `throw` or `switch`, use a `goto`. – S.Lott Feb 21 '11 at 22:21
  • Maybe just collect together all of the examples showing that it is never necessary, and almost never desirable where alternatives exist. – Marcin Feb 22 '11 at 07:59
  • http://stackoverflow.com/questions/3339946/how-to-avoid-long-chain-of-frees-or-deletes-after-every-error-check-in-c/3339958#3339958 – karlphillip Nov 28 '11 at 20:53

9 Answers9

1

Switch sentence can be kind of use.

Actualy any loop is using (internaly) CPU op-code goto instruction!

But normaly is no need to use goto statement if we are talking about high level languages, but in assembly language is goto statemen something normal.

GJ.
  • 10,810
  • 2
  • 45
  • 62
1

The only time to use goto is when no other control construct available to you can provide that behaviour.

As GJ says, the main time is when you don't actually have anything that can perform iteration, as when you are in assembly land.

Marcin
  • 48,559
  • 18
  • 128
  • 201
1

goto usage should be ok in program which demonstrates problems of spaghetti-code.

Snowbear
  • 16,924
  • 3
  • 43
  • 67
1

This C++ example is arguable:

if(a)
{
    ... // case 1
}
else if(b)
{
    if(c)
    {
        ... // case 1 again
    }
    else
    {
        ... // case 2
    }
}
else
{
    ... // case 3
}

The problem here is that you must either duplicate the code in the if() for case 1, or you must duplicate the code for handling case 1. In that example, the handling code was duplicated. See this alternate no-goto solution:

if(a || (b && c))
{
    ... // case 1
}
else if(b && !c)
{
    ... // case 2
}
else
{
    ... // case 3
}

Seems fine, except when the duplicated code is something very complicated. Then you start pulling things out into intermediate variables... moving logic away from the place where it's demanded.

Here's a solution using goto which doesn't have compromises:

if(a)
{
case1:
    ... // case 1
}
else if(b)
{
    if(c)
    {
        goto case1;// case 1 again
    }
    else
    {
        ... // case 2
    }
}
else
{
    ... // case 3
}

In C++, scope is something to consider. goto in C++ is about the only way of jumping around execution with liberal regard to scope.

Even if arguable, I still would not use goto in the sample I gave, because it complicates the order of execution. Knowing the state of things at case1: is really not very intuitive.

tenfour
  • 36,141
  • 15
  • 83
  • 142
1

An oft neglected point is that a GOTO can significantly simply a horrendous mess of if/else statements of spaghetti business code.

And before you downvote me for making such a statement, realize that business logic can be horribly complicated. I mean sometimes your only options are to create a bunch of boolean variables, set/unset them in the if/else mess, and then in the later portion of the code after you've escaped from the if/else nest to frob the widget when variable 5 is set as opposed to a GOTO statement.

Those who tote the line "never" only show their lack of adaptability and ignorance.

hova
  • 2,811
  • 20
  • 19
0

There are a few very random cases where a goto can be more readable and possibly safer when it comes to code maintenance. The first one that comes to mind is the "also" code problem:

//...

if(a)
{
    //do a
}
else if(b)
{
    //do b
}
else if(c)
{
    //do c
}
else goto skip_also_stuff;
{
    //if any if in the chain was true, do this too
    //do if a and b and c
}
skip_also_stuff:

//...

There are many other ways to do this, but most solutions leave open many places where future changers may forget to update something. I find this solution to be more simple as it skips unnecessary compares and/or code duplications. Control flow in all languages I have ever seen have a logical "or" with else statements, but no "and" like an "also" statement.

Cory-G
  • 1,025
  • 14
  • 26
0

Exception handling.

A "raise" or "throw" statement is a kind of goto.

S.Lott
  • 384,516
  • 81
  • 508
  • 779
  • 2
    With the same reasoning, `if`, `while` and `for` statements are also "a kind of goto". – Matti Virkkunen Feb 21 '11 at 21:21
  • 1
    Not really. Exceptions end the current sequential execution -- there is no execution after the raise or throw statement. No post-condition to that statement of any kind. `if`, `while` and `for` have post-conditions that are often very well-defined. – S.Lott Feb 21 '11 at 21:23
  • And please see my edit. It has to be the goto statement itself, not an alternative type of goto. But thanks for the suggestion. –  Feb 21 '11 at 22:11
  • @Ross: You're not thinking about the answer. Use the `goto` the way you'd use a `raise` or `throw`. – S.Lott Feb 21 '11 at 22:20
0

Here is an example:

while(...){
    switch(...){
     ...
     goto loop_done;       // break won't work here
    }
 loop_done: ...
Dan D.
  • 73,243
  • 15
  • 104
  • 123
shix
  • 55
  • 2
  • 8
0

The answer from shix is spot on. I find that the only reasonable use of goto is when breaking out of a deeply nested loop.

This is a contrived example:

#include <stdio.h>

int main()
{
  // find 6 positive numbers less than 100
  // , half odd
  // , half even
  // , that add up to a multiple of 123

  int n1, n2, n3, n4, n5, n6;

  for (n1 = 2; n1 < 100; n1+=2) 
    for (n2 = 2; n2 < 100; n2+=2) 
      for (n3 = 2; n3 < 100; n3+=2) 
        for (n4 = 1; n4 < 100; n4+=2) 
          for (n5 = 1; n5 < 100; n5+=2) 
            for (n6 = 1; n6 < 100; n6+=2) 
              if (((n1 + n2 + n3 + n4 + n5 + n6) % 123) == 0) 
                goto found; 

  printf("tested all numbers less than 100, couldn't find an answer\n");
  return 0;
found:
  int sum = n1 + n2 + n3 + n4 + n5 + n6;
  printf("answer: %d + %d + %d + %d + %d + %d = %d ( %% 123 is %d)\n", 
         n1, n2, n3, n4, n5, n6, sum, sum % 123);
  return 0;
}
Okken
  • 2,536
  • 21
  • 15