# How do I do this without using goto statements?

This topic is 3432 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Right now I am working on a program that generates pseudo code from an activity diagram. I am working out some diagram scenarios and trying to put it into code to help me come up with a plan to code the translation. There is one that I can’t figure out how to do without using a goto statement and I know that as a rule of thumb C++ programmers are not supposed to use those. This is the code that best describes the graph
	while(func1()==true)
{
func2();
while(func3()==true)
{
func4();
if(func5()==true)
{
goto g1;
}

}
func6();
}
g1:
func7();


Also, if I were to copy everything after the outer while loop into the if statement and then return like in the code below, it would be way too impractical.
	while(func1()==true)
{
func2();
while(func3()==true)
{
func4();
if(func5()==true)
{
func7()
return;
}

}
func6();
}

func7();


Anyone know how I can do this? Is there a way I can use a double break or something? [Edited by - ManaStone on August 18, 2008 3:14:23 AM]

##### Share on other sites
Sometimes goto is not the ultimate evil. It's ultimate evil to some guys who spend all of their lives to write a book on how to write clean code.

In industry goto sometimes is way better than ugly hacks that are invented just to avoid it.

It's just like OOP, when it's too much, it's PITA.

##### Share on other sites
Just leave it. It's fine like that. goto is only bad if abused. It comes in handy in certain situations, hat's why it's still included in modern languages.

##### Share on other sites
Just use a flag

bool finished = falsewhile (!finished && func1()){	func2();	while(!finished && func3())	{		func4();		finished = func5();	}	if (!finished)	{		func6();	}}func7();

It looks like more typing, but a properly named flag that describes the loop will help readability. I have faith that any decent compiler will optimise it to the same thing as well.

##### Share on other sites
You could use a flag:

bool done = falsewhile(!done && func1()==true)	{		func2();		while(!done && func3()==true)		{			func4();			if(func5()==true)			{				done = true;			}					} 		if (!done) 		        func6();	}	func7();

It's likeley that there's a more elegant solution, depending on what funcs 1-6 actually do.

##### Share on other sites
Thanks for the advice. I'll probably end up using the goto though. Generating all the additional code for flags looks like it would be more tedious than it needs to be. I really wish C++ had the ultimate break that would get out of every loop. Perhaps I'll just have the pseudo code say Complete Break and then the programmer writes the code he can just add in the flags.

##### Share on other sites
Just use the goto. Yes, you could use some signal flag, but that would just make the code less intuitive. Give the label some descriptive name, add a comment what is done and it's quite comprehensible what happens.

The reason most programmers detest goto is that it can be used to make incomprehensible code. Using goto to break out of nested loops is fine. Using goto for any other flow control is frowned upon, especially if one jumps backwards in the program.

##### Share on other sites
Is the goto in your generated code, or your actual code? Gotos tend to be much more common (and more tolerated) in generated code since (in theory) no one ever has to maintain it directly, and can simplify the generating code.

##### Share on other sites
You could create another function, that will hold inner loop:

func8:    while(func3()==true)    {        func4();        if(func5()==true)        {            return true;        }		    }    return false;main:    while(func1()==true)    {         func2();         if (func8()) break;         func6();    }    func7();

##### Share on other sites
mceier does have an element of the solution. If your two inner loops somehow form a compact set of functionality that can be jumped out of, then that set of functionality should be given a name and placed in its own method. The actual details of how this should be happening obviously depend on the exact algorithm being used. Therefore:

void factored_method(){  while(func1())  {    func2();    while(func3())    {      func4();      if(func5()) return;    }    func6();  }}void original_method(){  factored_method();  func7();}

##### Share on other sites
Wow! A double break! That's a cool idea! I wrote my own compiler that's roughly C/C++. I might add that. It's funny -- I learned there was a "continue" statement in C/C++. I had never used it or seen it. I added it, just kinda guessing what it might do. (Too lazy to check a standard compiler.)

##### Share on other sites
Losethos: from my language design experience, adding features to a language because they are "cool" is an excellent way to get an overly bloated and badly fitting language. Always consider the many alternatives that have already been invented by other language designers before rolling out your own. A good example would be Java's labeled break statements, which are by far superior to anything "double break" may mean.

##### Share on other sites
ToohrVyk. Yeah, your right, but I already did it. It's kinda a gimick, I guess.

##### Share on other sites
Quote:
 Original post by ManaStoneI really wish C++ had the ultimate break that would get out of every loop.
That's exactly what your goto statement did. It jumps out of your loop to another address, just like a break would do.

What's the big deal? You must have read too deep into someone's anti-goto sentiments. That rule gets hammered into people way too much. People learn how to properly write functions and classes these days, we aren't 6 months out from people writing oldschool 'goto linenumber' BASIC code.

The only bad thing that can happen is that you create spaghetti code that is impossible to follow. You haven't done that here. It's a perfectly valid flow control statement.

##### Share on other sites
ToohrVyk,

On second thought, I removed the double_break. Thanks for talking me out of it. Goto is fine and actually clearer since the label catches your eye -- no need to bloat the language.

##### Share on other sites
The double_break added a bunch of parameters to internal compiler routines, slowing it down... Thanks to you, I was inspired to remove the "continue" statement too! I don't use that crappy thing. If I were a teacher, "goto" would be fine in very limited circumstances but that "continue" statement would be banned because no real-world programmers use it! Let's take a poll... anybody use the C/C++ "continue" statement? Screw that--keep my compiler lean.

##### Share on other sites
Quote:
 Original post by losethosLet's take a poll... anybody use the C/C++ "continue" statement? Screw that--keep my compiler lean.

I do, more than break actually (you can break out of a loop by correct use of the loop condition, but selectively dropping out of a loop iteration before it's over is harder).

As far as 'continue' goes, it should be fairly easy to implement on most code generation architectures with at most a single additional parameter: it is usually implemented as a "goto end;" with a fresh "end:" label being added automatically at the end of the loop body. It can even be done at parsing time!

##### Share on other sites
I do occasionally, why not? I tend to take opinions lightly when someone says DONT EVER DO X, simply because it is situation dependant.

##### Share on other sites
I use continue in loops quite often, sometimes it is really clear and fast solution.

##### Share on other sites
This doesn't really give enough context to find a solution. One, perfectly valid solution is this:
try {  while(condition1())  {    func1();    while(condition2())    {      func2();      if(condition3()) throw std::exception("Some error");    }    func3();  }} catch (std::exception &e) {} func4();

If condition3 represents an error, then exceptions are what can be used.

The core of the problem here lies simply in that individual functions do not encapsulate functionality well, since they need to manipulate caller's context.

But all of this is mostly pointless. *Which activity?* Tweaking a solution doesn't bring many benefits if the solution itself is unsuitable.

##### Share on other sites
Quote:
 Original post by Daaark That's exactly what your goto statement did. It jumps out of your loop to another address, just like a break would do.What's the big deal? You must have read too deep into someone's anti-goto sentiments. That rule gets hammered into people way too much. People learn how to properly write functions and classes these days, we aren't 6 months out from people writing oldschool 'goto linenumber' BASIC code.

Um, sure you could use a goto. But *why*? Why not do the proper solution and put the loops in their own function, from which you can return. No need for goto, no need for multiple breaks. Just return when you want to exit the loops.

Nested loops are the most common justification for gotos I see. And it's still wrong. That's what functions are for. You should get used to those. They're there for a reason.

And this is exactly why use of goto is generally discouraged. Because it creates programmers whose solution to everything is "one long function, and use goto instead of factoring out into smaller functions".

I agree, the use of goto in this case isn't overly hard to follow, but it's still pointless, because you can achieve the same without using goto.

And the problem is that even if your use of goto is harmless, the programmer reading the code doesn't know that. He still has to read through the code verifying which gotos jump to which labels, and vice versa, to even figure out whether or not it's spaghetti code.

If you need to be able to jump out of a block of code, then that block should be a separate function.
If you need to be able to jump *to* a block of code, then it should most likely also be a separate function.

I know that almost every C/C++ programmer starts out cramming everything into the main() function. And then they start writing one or two other functions, and still cramming everything into those.
And then they do like you, saying "Oh, but my code doesn't fit, I'd better use some gotos", when they should just accept that they're going to have more than 3 functions in their program.

##### Share on other sites
[quote]Original post by Spoonbender
Quote:
 Original post by Daaark That's exactly what your goto statement did. It jumps out of your loop to another address, Um, sure you could use a goto. But *why*? Why not do the proper solution and put the loops in their own function, from which you can return. No need for goto, no need for multiple breaks. Just return when you want to exit the loops.
Because some nested loops don't want to be separate functions. Choosing function granularity to avoid ever having to use goto is screwed-up priorities.

##### Share on other sites
Quote:
Original post by Spoonbender
Quote:
 Original post by Daaark That's exactly what your goto statement did. It jumps out of your loop to another address, just like a break would do.What's the big deal? You must have read too deep into someone's anti-goto sentiments. That rule gets hammered into people way too much. People learn how to properly write functions and classes these days, we aren't 6 months out from people writing oldschool 'goto linenumber' BASIC code.

Um, sure you could use a goto. But *why*? Why not do the proper solution and put the loops in their own function, from which you can return. No need for goto, no need for multiple breaks. Just return when you want to exit the loops.

Nested loops are the most common justification for gotos I see. And it's still wrong. That's what functions are for. You should get used to those. They're there for a reason.

And this is exactly why use of goto is generally discouraged. Because it creates programmers whose solution to everything is "one long function, and use goto instead of factoring out into smaller functions".

I agree, the use of goto in this case isn't overly hard to follow, but it's still pointless, because you can achieve the same without using goto.

And the problem is that even if your use of goto is harmless, the programmer reading the code doesn't know that. He still has to read through the code verifying which gotos jump to which labels, and vice versa, to even figure out whether or not it's spaghetti code.

If you need to be able to jump out of a block of code, then that block should be a separate function.
If you need to be able to jump *to* a block of code, then it should most likely also be a separate function.

I know that almost every C/C++ programmer starts out cramming everything into the main() function. And then they start writing one or two other functions, and still cramming everything into those.
And then they do like you, saying "Oh, but my code doesn't fit, I'd better use some gotos", when they should just accept that they're going to have more than 3 functions in their program.

In order to stay away from perfectly valid and harmless goto you just add a whole lot of register pushing and popping on the stack in inner loop. (Inline f/n's and optimizations might or might not work here, they are suggestions after all)

Don't invent some frighteningly insane constructs just to avoid goto, if it's clear and valid, use it. If someone have a problem with understanding the original code, he shouldn't be a coder in the first place.

##### Share on other sites
Quote:
 Original post by SpoonbenderAnd the problem is that even if your use of goto is harmless, the programmer reading the code doesn't know that. He still has to read through the code verifying which gotos jump to which labels, and vice versa, to even figure out whether or not it's spaghetti code.
I disagree with everything you wrote here.

His goto is not hard to follow. It's like a 3 line jump, and it's plain as day. Spoon, you're like a lot of people here who love to over engineer solutions to simple problems. You talk about hard to follow things, and then you suggest a completely un-needed, more complex work around to solve a problem that doesn't even exist!

goto is no different than any other keyword in the C derived languages, and can be used well, or abused and used very poorly. This case is not one of the later. This use is exactly what it's for.