Jump to content
  • Advertisement
Sign in to follow this  
Arclight

Breaking out of loops, in C?

This topic is 5085 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

Advertisement
Quote:
Original post by Extrarius
Oh, and for those that may have misunderstood me: Yes, break (and mid-function returns) are _REALLY_ great things. Without them, code becomes much more complex.

No, code doesn't become more complex, it just looks more complex. break and mid-function return hide complexity. Which usually is what you want.
Avoiding complexity is better than hiding it though...

Share this post


Link to post
Share on other sites
look, whether or not a return in the middle of a function is always bad is debatable, and whether or not a break or continue inside a loop is bad - is the exact same debate.

using more than one return, and using any arbitrary jump, goto, break, or continue, all violate the rules of structured programming. Period.

That doesn't mean they are bad, not usefull, or any other thing, but BY DEFINITION they violate structure programming - which insists that all code have only one entry and one exit point - including function returns and loop exiting.

Notice there is no rule about how you declare variables, or how you increment loop counters, only HOW YOU ENTER AND EXIT BLOCKS OF CODE!

sometime in the 60s or early 70s they proved that such a system COULD acomplish all possible programming tasks that can be acomplished on a von neuman computer. They also showed that a properly implemented compiler (compiling properly implemented code) can generate code just as efficient as when compiling code using jumps, gotos, and breaks ...

None of that means breaks of bad, or cannot be used. They are in the language for a reason - because a language is just a tool for a human to comminicate using ... and whatever method an individual finds easier to communicate with is the better method (assume that the same amount of data is retained and communicated).

But here are things to consider when you use them:

The main problem with all such breaks or continues is that they are not visible when skimming over the code (imaging a sections of ifs and loops that goes 4-5 levels deep, implementing a Multiway Tree insertion algortihm or something...). When you look at a loop that says

//find the next item that matches
while(currentItem != 0)
{
// some break in here when it finds the item, and another if it passes the item in a sorted list or something ....
}

sure the comment tells you what the loop is supposed to do (and you don't know if it's truth or lie in any code you haven't read) - but the control structure implies only that it stops when the currentItem is null ... which makes it fairly obvious that there is either a major bug here - or that a break or goto is involved ... so in this case it is fairly harmless to the confident reader.

But the point of all code is first - correctness to the computer, and second - readability to the future programmer.

Keep an eye on what a programmer is being told by your comments and conditions, types and variable names, and you will not stray too far ... don't insult their intelligence (like: int numItems; // the current number of items) but don't expect that they know exactly what was in your head when you wrote the code, nor what they are going to discover if the ever read the WHOLE function line-by-line. The point of all design rules is to reduce the amount of knowledge necessary, or the amount of lookup required, to work correctly within the system ...

Share this post


Link to post
Share on other sites
>>Returns not at the end of a function are considered 'incorrect' more often than break itself is, so actually your solution isn't really one =-) <<

Well, maybe in academia :-) However, I'd wager that most professional programmers would far prefer this:

function()
{
if (!conditionOk)
return;
if (!conditionOk)
return;
if (!conditionOk)
return;
if (!conditionOk)
return;
DoWork;
}

Over this:
function()
{
if (conditionOk)
{
if (conditionOk)
{
if (conditionOk)
{
if (conditionOk)
{
DoWork;
}
}
}
}
}

Share this post


Link to post
Share on other sites
DrNecessiter: It depends on what you mean by professional programmer. I work as a programmer right now and I much prefer the many returns, but the standards at my place of work do not allow multiple returns or breaks, so like I said in my previous post I have to work a lot harder to make code that ends up being more complex (because I have to have extra conditions in loops and many, many if tests inside them for example to simulate a 'break') and break it into multiple functions to keep the indentation down.

Share this post


Link to post
Share on other sites
Wow... what a pain! I'd say those standards need to be reassessed :-)

Plus, maybe I've just been lucky, but I've never been in an environment where those types of standards were regulated. Naming and formatting conventions, yes, but not that. Ugh. How frustrating! Maybe the standards were set up by ex-COBOL programmers!

Share this post


Link to post
Share on other sites
Sounds like your lecturer is one of those annoying ivory-tower type academicians... my god I hate them.

Those that can, do. Those that can't...

Share this post


Link to post
Share on other sites
Offtopic: a legitimate use of goto
int main(int argc, char* argv[])
{
logger.start(true);
Kernel* k=new Kernel(argc, argv);
if (!k->init()) { LOG("Kernel initialization failed."); k->exit(); goto cleanup; }
if (!k->mainloop()) { LOG("Kernel aborted with error.",logger.LOG_CRIT); k->exit(); goto cleanup;}
if (!k->exit()) { LOG("Kernel exited with error.",logger.LOG_WARN); }

cleanup:
delete k;
logger.stop();
return 0;
}

Is there a cleaner way to do this?

Share this post


Link to post
Share on other sites
Quote:
Original post by thedustbustr
Offtopic: a legit use of goto
*** Source Snippet Removed ***Is there a cleaner way to do this?

It'd be even more legitimate if logger.start could fail.

Then you'd have a cleanupall: and cleanuplogger: labels at the end.

The linux kernel uses this style extensively, especially for locking.

Share this post


Link to post
Share on other sites
Aren't exceptions designed for that purpose?

[edit: oops, in plain jane C; iirc, atexit() and the such could easily do something similar in a manner without the goto]

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.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!