Question

I'm wondering what I should be using instead of goto statements?

Should I be using nested if/while/do-while statements?

They say that using goto creates 'spaghetti code', but surely if someone is writing a large console application and they have if statement after if statement in an attempt to control the flow, that's going to make a mess?

I'm asking as many people have asked why the goto statement is bad, but not what to replace it with. I'm sure a lot of beginners could do with this.

This is for C++.

Was it helpful?

Solution

You are much better off using functions, loops, and conditional statements. Use break and continue as necessary.

I can nearly guarantee you any situation in which you are utilizing goto there is a better alternative. There is one notable exception to this: multi-level break.

while(1){
    while(1){
        goto breakOut;
    }
    //more code here?
}
breakOut:

In this one (relatively) rare situation, goto can be used in place of a typical "break" to make it clear we are actually getting out of a nested loop. The other way to approach this is with a "done" variable:

while(!done){
    while(!done){
        done = true;
        break;
    }
    if(done){break;}
    //More code here?  If so, the above line is important!
}

As you can see, the done variable is more verbose when you have additional processing in outer loops, so a goto is a cleaner way of breaking free!

However, in 99% of cases you really, really, don't want to start writing a bunch of goto statements. Really think through each one.

With functions the above could also be written like so:

bool innerLoop(){
    while(1){
        return false;
    }
    return true;
}

...
while(innerLoop()){ //can only be written this way if the inner loop is the first thing that should run.
    //More code here?
}
...

Sometimes breaking an inner loop out in this way can be messy if there are a lot of dependencies on the outer one. But it remains a viable way of breaking out of code early with return statements instead of goto or break.

OTHER TIPS

If you can write your logic using a clean, modern construct, then use it. Otherwise, if goto makes sense, use it.

In general, goto can make your code harder to read and follow the flow of the code. For that reason, newbies are told to avoid goto altogether. This encourages them to think in terms of other constructs.

But some people just get religious about it. Coding is not a religion. And if a goto makes sense, C++ has a perfectly valid goto statement and you should use it when it makes good sense.

It doesn't make sense to me to ask what you should use instead of goto. You can generally use some type of loop or other construct, depending on what you are doing. But where goto makes sense, use it.

Don’t listen to people who say "never use goto". You're quite right that there are cases where nesting scoped blocks will make a heck of a lot more mess than a goto. It has its place, just as a switch/case does. However, with functions you can often refactor away the entire argument and keep people happy.

Simply forget that there is the goto statement in C++ and there will not be questions about how to replace the goto.:)

As for me I never see a code with goto statement that I could call it as a good code. Usually a goto statement is the source of some kind of errors and difficulties. Especially it is difficult to modify such code. Moreover one goto statement usually starts to produce other goto statements in the code.:)

The goto is bad because it allows you to jump from context to context. The context is a vector of all your variables (with their values) at a particular point of your program. A program execution graph shows you how your program jumps from context to context. It's in your best interests to keep the execution graph as simple as possible. The simplest one is a chain, the next step is an execution tree. A loop adds complexity, but it's a managed complexity. If you have a node in your execution graph, which is reachable via more than one execution path, and you need to understand a context at this node, then you'll need to follow more than one execution path back. These "merge" nodes add a lot to the complexity of your program. Each labeled statement (the goto target) is a potential merge node.

So, try don't use the goto operator at all - the language itself will force you to find a manageable solution using loops, boolean variables, classes, functions etc. and your program will be more clear and understandable. C++ exceptions is another manageable way to jump between contexts.

There are computing geniuses, who can keep in their minds and process very complex execution graphs, so they don't care much about complexity of their programs or a next programmer, who will be assigned to support or take over their code in the future. I guess, we have some of them here :-)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top