tags:

views:

473

answers:

11

Hi, I know using goto is something most people say to avoid, however I have read on various places that sometimes it is useful if you need simple code. Currently I have very simple program that needs to be repeated if user selects so:

static void Main()
{
    Restart:
    ...

    string UserChoice=Console.ReadLine();
    if (UserChoice=="y")
    goto Restart;
}

Is using goto here really so bad? I just cannot see any other way how to repeat the code without doing loops etc. This seems to be very straightforward and clean way. Or am I missing something?

+5  A: 

instead write something like below.

while(Console.ReadLine() == "y")
{
.....
}

Yes using goto is bad because it makes your code less readable.

Numenor
Acccording to his example, it seems that he want to do some logic before the Console.ReadLine, so this will not behave exactly as his current code, as it reads from console first, then perform the logic.
Øyvind Bråthen
If thats the case do { ... } while(Console.ReadLine() == "y") will work.
Numenor
@Numenor: Agreed. I think that is the cleanest way of doing it. Good answer!
Øyvind Bråthen
+5  A: 

Of course if your code is going to do the same thing again and again, you have to add a loop. That's much better than goto.

Use something like this

string UserChoice = "y";
while( UserChoice == "y"){
  ...
  UserChoice=Console.ReadLine();
}

That should work out well for you.

Øyvind Bråthen
-, you got some logical mistake in here: it should loop while the user does not input "y" which is wrong - it should loop while the user inputs "y"
Andreas Niedermair
@Andreas: Thanks. Fixed it now. Goto got to my head I guess ;)
Øyvind Bråthen
removed downvote as you've corrected your answer!
Andreas Niedermair
this does not match posters logic. Also the loop condition is always false.
Bear Monkey
@Andreas Its still wrong...
Bear Monkey
i know :) ... but the dots could stand for a method call which could be inserted before the while either ... see, 50/50 ...
Andreas Niedermair
@Andreas no i mean it never runs anything cause UserChoice is initialised wrongly.
Bear Monkey
reread my comment: `...which could be inserted before the while either...`
Andreas Niedermair
@Andreas Never heard of 50/50 rule Ive always used ... to only mean other statements. Oh and he just fixed it to be initialised correctly to "y", so i guess he didn't mean what you said :)
Bear Monkey
@bear: what i mean with `50/50` is: `- for missing the initial execution, + for the option i've mentioned` ... so `+` and `-` compensate each other...
Andreas Niedermair
@bear and @andreas: Now I hope both is pleased with the example :)
Øyvind Bråthen
@Øyvind Of course!
Bear Monkey
+3  A: 

I'd use a do/while loop:

string UserChoice = "";
do {
    ...
    UserChoice=Console.ReadLine();
} while(UserChoice == "y");
Lee
-, this will generate a compiling error due to scope issues...
Andreas Niedermair
removed downvote, due to correction of halfdan ... btw: why do all the guys use `""` ... :)
Andreas Niedermair
@Andreas maybe cause its quicker to type when making a fast answer
Bear Monkey
then why not use `var` :) ... you know ... reason not really consistent ...
Andreas Niedermair
@Andreas Maybe he has .Net 2? ;)
Bear Monkey
@bear monkey: i did not read any framework restriction...
Andreas Niedermair
@Andreas ok im a bad joker.
Bear Monkey
:) hehe........
Andreas Niedermair
+2  A: 

You could use a recursive function to do the same without loops:

public static void Main(string[] args)
{
   PrintChoices();
}

private static void PrintChoices()
{
    string userChoice = Console.ReadLine();

    if (userChoice == "y")
        PrintChoices();        
}
iCe
You could (in extreme cases) run into "recursion too deep" problems, that you don't have in the loop situation.
Hans Kesting
Sure, I recommend as always in production code, adding a limit to avoid the recursion deep limit problem. Also, I prefere the looping option however he asked to do the same without using a loop.
iCe
+2  A: 

Using methods instead of GOTOs is more widely accepted:

static void Main()
{
    Restart();
}

static void Restart()
{
    ...code

    string userChoice = Console.ReadLine();
    if (userChoice=="y")
        Restart();
}
Chris S
C# doesn't yet optimize for tail-recursion (correct me if I'm wrong), so this would grow your call-stack. Probably not a problem if this is user-controlled (as in your example), but consider if you run Restart() thousands of times. Stack Overflow, hello?
Zano
No hard to check if tail call is implemented ildasm and check for http://msdn.microsoft.com/en-us/library/system.reflection.emit.opcodes.tailcall(VS.95).aspx
VirtualBlackFox
It' an interesting point @Zano, but 15000 user interactions seems a bit unlikely (for a console app).
Chris S
^ Should read 1500, obviously that depends how much code is in `Restart()`
Chris S
A: 

Personally I have never had to use a goto, and like Øyvind Bråthen and Numenor have stated the loop method is by far the best way of doing this task.

However, there is one case that I can think of where a goto would be helpful

As a switch “fall through” is illegal in C# (causes a compiler error):

switch (a) 
{ 
    case 3: 
        b = 7; 
    case 4: 
        c = 3; 
        break; 
    default: 
        b = 2; 
        c = 4; 
        break; 
}

To get it to work you can use a goto:

switch (a) 
{ 
    case 3: 
        b = 7;
        goto case 4;
    case 4: 
        c = 3; 
        break; 
    default: 
        b = 2; 
        c = 4; 
        break; 
}
jimplode
-, relation to the question??
Andreas Niedermair
a valid reason for using the goto. I stated the loop was a better option and also provided the only real use I can think of for a goto.
jimplode
damn ... read the question: `Is using goto here really so bad? I just cannot see any other way how to repeat the code without doing loops etc.`... how does your answer capture loops?? so it should rather be a comment
Andreas Niedermair
It relates to the nature of the goto and where it is acceptable to use it. The goto statement is generally not a good move!!
jimplode
once again, repeating myself: your answer provides some more info about `goto`, but this was not asked... the question was: `Is using goto **here** really so bad? I just cannot see any other way how to repeat the code without doing loops etc.` ... you're off the subject!
Andreas Niedermair
Well I am sorry you fail at programming and take it so personally when people try and help you understand things.
jimplode
the more you argue about, the more you agree with my objection and downvote :) *your answer should be a simple comment, that what they are for*
Andreas Niedermair
Who is arguing, the downvote is your call, and it does not bother me. Your attitude has a lot to be desired though, and when people genuinely try and give helpful advice you should take it as such. I stand by my reply.
jimplode
@jimplode: I actually liked your answer. I just recently started coding in C# after spending years coding in C++ and I was quite surprised that C# doesn't allow switch case fall throughs as they can sometimes be quite nifty and useful. I like your work around for that.
xbonez
@xbonez: Thank you, was just trying to give insight into a valid use of goto.
jimplode
@xbonez: "quite nifty" is seldom a good thing when talking about production code.
Zano
@Zano: gotta agree with you. Using switch case fall throughs is something I probably won't do in production code. its still good to know that it can be done. Useful at times
xbonez
jimplode
+1  A: 

Use a do while loop to replace your goto as its much more readable.

do 
{
...
}
while(Console.ReadLine() == "y");
Bear Monkey
+15  A: 
string userchoice;

do {                

    userchoice=Console.ReadLine();

} while (userchoice=="y");
mumtaz
+2  A: 

There is one basic solution missing in the answers,

while (true)
{
    ...
    if (other-stop-condition) break;     

    ...

    string UserChoice=Console.ReadLine();
    if (UserChoice != "y") break;
}

The break statement is considered to be less structured than a pure while but more structured than a (real) goto. It should be used sparingly, but it has its uses like with the other-stop-condition

is using goto here really so bad?

Not in this simple program. But if you continue to use goto to replace loops, if/then etc your code will increase in complexity much faster than code that avoids goto.

Henk Holterman
Your replacing a goto with a break which is just another type of goto although less offensive ;)
Bear Monkey
@Bear Monkey: Right, I forgot some comment.
Henk Holterman
@Henk Im sure you knew that. Sometimes people use break, continue and return statements freely but then tut in horror at gotos without realizing that those flow of control statements can be just as bad as a goto.
Bear Monkey
A: 

I agree with Jimplode, Andreas the idea of forums is dissemination of information ideas, if you are not happy with what peoples ideas or opinions are, then dont take them on board.

Cas
-, that should be a comment, not an answer ... just to be clear: i'm happy with any answer or comment (with opinions either), but the choice of writing either an answer or a comment should be correct...
Andreas Niedermair
Not everyone can comment!! you need reputation to comment!!
jimplode
@jimplode: That is really a lousy reason to use answers as a soapbox. Answers are for answers, period. If you lack reputation, get some, don't abuse the system.
Zano
I was just saying why this would not be a comment. I do use comments, but not everyone can. So if they have something to say, which is what this entire site is for, how do they say it?
jimplode
@jimplode: They don't. I can sympathize with a strong urge to say "mee too", but answers are not "answers to question or comments from users with not enough reputation". Simple as that. If you have a new answer to the question – by all means – add it. But for some reason (actually, experience), the powers that be decided that the right to comment must be earned. If you don't like it, feel free to use experts-exchange.
Zano
This was not even my answer, I like this site, and try to be helpful, shame the internet is so full of people that get soooo enraged by the smallest of things. :)
jimplode
+4  A: 

Is using goto here really so bad?

In March 1968, Dijkstra sent a letter to Communications of the ACM which was published under the title Go To Statement Considered Harmful. It is an interesting read, and part of programmer lore.

The argument against GOTO presented in this letter has to do with how programmers build a mental model to track the progress of code execution. Dijkstra argues that such a mental model is important, because the value of variables is meaningful only relative to the execution progress. For example, when our program is counting the number of times an event occurs, there is always an in-between moment where N events have occurred, but the variable keeping track of it has not yet been incremented and is still at N-1.

He goes through these steps in his reasoning against GOTO:

  1. First consider a very simple language without procedures, loops or GOTO. In such a language, the programmer can mentally track execution by imagining an execution pointer advancing from the start of the file to the end. A single index (i.e. the line number) suffices to model execution progress.

  2. Now we add procedures to the language. The execution progress can no longer be tracked by a single index, as it might be inside a procedure. We also have to keep track from which line the procedure was called. Also, procedures can be called from other procedures. Therefore, we model execution progress as a sequence of indices. (In real life, programmers call such a sequence a "stack trace".)

  3. Now we add loops to the language. For each line in our stack trace that is inside a loop body, we need to add another type of index to model execution progress: the repetition count.

  4. Now we add GOTO. Dijkstra argues that with unbridled use of GOTO, our ability to track execution progress now breaks down. We can still track execution progress with an "execution clock" by saying "now we're executing the 152nd statement". However, this is not really helpful to establish the context that is necessary to interpret the values of variables.

As long as we only use GOTO statements to build simple loops, you can argue that the situation is equivalent to point (3), and there is no problem. But in that case you can just use the loop constructs. Better to just keep GOTO out of your code, so that you don't slip into the situation described in point (4).

Wim Coenen
I would add that gotos are often considered acceptable in auto-generated machine-consumed code. Indeed for auto-generated statemachines they can be the only sensible option.
Bear Monkey