Early returns

Started by
16 comments, last by Nemesis2k2 18 years, 10 months ago
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.
STOP THE PLANET!! I WANT TO GET OFF!!
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.
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
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. ;)
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.
RIP GameDev.net: launched 2 unusably-broken forum engines in as many years, and now has ceased operating as a forum at all, happy to remain naught but an advertising platform with an attached social media presense, headed by a staff who by their own admission have no idea what their userbase wants or expects.Here's to the good times; shame they exist in the past.
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!
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.
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.
STOP THE PLANET!! I WANT TO GET OFF!!
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.
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.
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.
--God has paid us the intolerable compliment of loving us, in the deepest, most tragic, most inexorable sense.- C.S. Lewis

This topic is closed to new replies.

Advertisement