Jump to content
  • Advertisement
Sign in to follow this  
Structural

Early returns

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

What's so bad about them? I've read a few WTF's on www.thedailywtf.com, and I came across a few comments that were along the lines of "haha, an early return". I must admit I sometimes have the same habbit of doing early returns, especially while doing parameter validation early in the function or when an error occurs during processing. Why are they so bad? And what is the better alternative? Adding levels of indentation with extra if's doesn't seem to make code more comprehensible in my opinion, but I could be wrong there.

Share this post


Link to post
Share on other sites
Advertisement
In languages where you have to manually insert cleanup code, you have to make sure that cleanup is done on every path your function can return by. That's why some advocate that a function should have a unique exit point. That's also an argument some people use against exceptions.

In C++, destructors and the RAII idiom make that completely unnecessary.

I much, much prefer an early return ("ok, you don't have to deal with all that stuff, return now") or throwing an exception ("your parameters are bad, I can't do anything with them" or "I can't return a meaningful result") to a series of nested if statements.

Share this post


Link to post
Share on other sites
Also, a bunch of exception throws or early return in the beginning of a method/function can't really harm clean up, since there's nothing to clean up yet.

However, early returns can be problematic when they are "hidden" somewhere in the middle of a method/function. They are quite easy to miss, if you have to maintain your old or foreign code.

So, in conclusion, I don't see problems with early return for parameter validation, but everything else should be avoided, if easily possible.

IMHO, of course. ;)

Share this post


Link to post
Share on other sites
The philosophy against early returns is just another throwback to the days of much simpler and more explicit programming languages, most of them simpler to the point that you can't really call them a language so much as syntactic sugar for machine code.

Not that syntactic sugar is bad. If it was a bad thing, we'd all be writing software with a hex editor.

Share this post


Link to post
Share on other sites
Wow, i just realized how much of a problem this can be.

I am looking at a piece of code of a loading funtion, and this has files being opened, memory being allocated, etc. And to make an early return i just realized i have to clean everything i did before if something goes wrong. That includes closing all the files, freeing all the memory and nulling all the pointers used in memory allocation to avoid double frees and reseting a bunch of variables, for every early return i have.

This turned out to be a mess!

Share this post


Link to post
Share on other sites
Quote:
Original post by xor
I am looking at a piece of code of a loading funtion, and this has files being opened, memory being allocated, etc. And to make an early return i just realized i have to clean everything i did before if something goes wrong. That includes closing all the files, freeing all the memory and nulling all the pointers used in memory allocation to avoid double frees and reseting a bunch of variables, for every early return i have.


If your using C++ you wouldn't have so much a problem if you used the standard library:

1. std::auto_ptr for RAII.
2. std::vector over C-style dynamic arrays.
3. std::basic_string over C-style dynamic strings.
4. C++ I/O file streams automatically closed when destructed.
5. using reference counted smart pointers.
6. pass by reference using (constant) references instead of plain pointers.

Share this post


Link to post
Share on other sites
Quote:
Original post by xor
Wow, i just realized how much of a problem this can be.

I am looking at a piece of code of a loading funtion, and this has files being opened, memory being allocated, etc. And to make an early return i just realized i have to clean everything i did before if something goes wrong. That includes closing all the files, freeing all the memory and nulling all the pointers used in memory allocation to avoid double frees and reseting a bunch of variables, for every early return i have.

This turned out to be a mess!


This is indeed a problem I recognise with using early returns, and at places like that I try to avoid them. I now have some duplicate cleanup code in some loaders because of this.
I also have the habbit of avoiding goto's like the plague, but sometimes I feel a "goto cleanup;" would really simplify some stuff.

Share this post


Link to post
Share on other sites
Quote:
Original post by Structural
but sometimes I feel a "goto cleanup;" would really simplify some stuff.


Not really, using what i suggested in my previous post would, take advantage of destructors.

Share this post


Link to post
Share on other sites
Quote:
Original post by Structural
This is indeed a problem I recognise with using early returns, and at places like that I try to avoid them. I now have some duplicate cleanup code in some loaders because of this.
I also have the habbit of avoiding goto's like the plague, but sometimes I feel a "goto cleanup;" would really simplify some stuff.


Interestingly enough, using some languages (like C# and Java for instance) you can have something like a "goto cleanup;" if you use the
try
{
// do stuff
}
finally
{
// cleanup
}
construct.

Share this post


Link to post
Share on other sites
Quote:
Original post by Rattenhirn
Interestingly enough, using some languages (like C# and Java for instance) you can have something like a "goto cleanup;" if you use the
try
{
// do stuff
}
finally
{
// cleanup
}
construct.

Prefer the using keyword to try/finally blocks in C# whenever the object being cleaned up implements IDisposable. The generated code is the same, but the using construct is considered idiomatic.

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!