Jump to content
  • Advertisement
Sign in to follow this  
ManaStone

How do I do this without using goto statements?

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

If you intended to correct an error in the post then please contact us.

Recommended Posts

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 this post


Link to post
Share on other sites
Advertisement
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 this post


Link to post
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.


That's what C/C++ function call overhead is all about...

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 this post


Link to post
Share on other sites
Quote:
Original post by Spoonbender
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.
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.

Share this post


Link to post
Share on other sites
IMO

Give me an exception or flag or inner function any day. Goto/break/continue harm readability and the ability to maintain the code. Maintenance is hard enough without convoluting common flow control.

Share this post


Link to post
Share on other sites
Quote:
Original post by Sneftel
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.


True, I didn't mean it should be some kind of completely automatic reaction to nested loops. Rather that it is *usually* the case that if you have some code that needs "multiple breaks", the simplest and cleanest solution is to just wrap it in a function you can return from.

My point is more pretty much the inverse of what you said. It's not "if you see a nested loop, always factor it out into a separate function", but rather "if you factor out your code into separate meaningful functions, you probably won't encounter a problem with breaking out of nested loops in the first place.
(Nitpick: Note the *probably*. I know it's not some kind of universal rule)

I'll be the first to admit that there are exceptions to most rules, but *usually* there are superior alternatives to gotos. And *usually* when people want to use gotos, it's because they're cramming too much functionality into a single function.

Quote:

That's what C/C++ function call overhead is all about...

What overhead? Most modern compilers are fairly good at inlining. If function call overhead scares you, I assume you don't use the standard library at all either? Most of that relies pretty heavily on the compiler being able to inline your code. std::vector would be a lousy data structure if you couldn't count on your compiler inlining access to it.

And as always, how about profiling before worrying about performance?

Quote:

Don't invent some frighteningly insane constructs just to avoid goto, if it's clear and valid, use it.

If you think a user-defined function is an "frighteningly insane", I think we have bigger issues than how to refactor a nested loop... [grin]

Quote:
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!

How do I know that no other goto will jump to the same label?
I can't tell that just by reading those three lines of code. That's hardly plain as day, is it?
Sure, it's easy to see that this goto will jump to the label a few lines under it. It's less easy to see, when looking at the label, which goto's will jump to it. I can see one of them, but I have no easy way of determining if there are others.

And if you think a function call is hard to follow, then I don't think you're one to talk about who "should not even be a coder in the first place". [wink]

Share this post


Link to post
Share on other sites
Seems to me that Spoonbender is saying the right things, but C++ makes it tedious to define functions for everything they *should* be defined for. With no support for unnamed functions, the overhead for creating a new function for one or two lines of code is enough that it's easier to just inline the function manually. It's annoying to have to jump all the way out of the function, write a new one, come back to where you were before, and call the function from there. It's also annoying to have to do this while reading someone else's code. It's even worse when it's a member function and now you have to edit a header file as well.

I think if functions could be defined within other functions, there would be much less argument towards what Spoonbender is saying. Since this isn't the case, the matter is very subjective.

Share this post


Link to post
Share on other sites
Spoon, we have these new things called comments, where one can easily say "this is used to break out of a nested loop blah blah blah" and there is no problem. You're only projecting problems from abusive cases onto this one, which works fine. Mana's implementation of the goto in this case is simple to follow, and clear as day. There is no need for some theoretical goto horror stories.

Share this post


Link to post
Share on other sites
Ordinarily if I were designing the function, I’d just split it up into other functions like spoonbender said, but for this program I can only create a new function if the user explicitly creates one.

Share this post


Link to post
Share on other sites
Quote:
Original post by PaulEdwards
I think if functions could be defined within other functions, there would be much less argument towards what Spoonbender is saying. Since this isn't the case, the matter is very subjective.


They sort of do exist in C++. Classes can be defined in functions and if you use a static member function in the class this effectively gives you local functions. Reference

Example:


int foo()
{
struct helper
{
static void go() { /* actions */ }
};

for(i = 0; i < WHATEVER; ++i)
{
helper.go();
}
}

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!