Is it a bad practice to have multiple returns? - multiple-return-values

Sonar Lint rule "Methods should not be too complex" (squid:MethodCyclomaticComplexity) has an example of using more than one return statement in the program block.
(see https://groups.google.com/forum/#!topic/sonarqube/BtvGoF6Tw7E for the cyclormatic complexity calculation rules)
The returns shortens the codes in a branch, and result with smaller code blocks. For example,
int findBranchNumber(String input) {
if ("branch1".equals(input)) {
return 1;
}
if ("branch2".equals(input)) {
return 2;
}
// ....
return -1;
}
The alternative will use a method variable (in this case) or bigger blocks. Whoever reads the code has to read the whole method before he/she realize only first 3 lines are relevant to the "branch1".
Please advise ...

I'm personally do as you show in example. Only be careful if you allocate resources (for example file opening, memory allocation and so on) and need be freed it on return from function. In this case can be used trick with goto line hire described in first answer https://stackoverflow.com/a/245761

Related

Good Coding Practices: When to Create New Functions

I have a certain function that uses the same (few, 2-5 depending on how I may change it to accommodate possible future uses) lines of code 4 times.
I looked at this question, but it's not specific enough for me, and doesn't match the direction I'm going for.
Here's some pseudo:
function myFunction() {
if (something) {
// Code line 1
// Code line 2
// Code line 3
}
else if (somethingElse) {
// Code line 1
// Code line 2
// Code line 3
}
else if (anotherThing) {
// Code line 1
// Code line 2
// Code line 3
}
else if (theLastThing) {
// Code line 1
// Code line 2
// Code line 3
}
else {
// Not previously used code
}
}
Those same 3 lines of code are copy/pasted (constructing the same object if any of these conditions are met). Is it a good practice to create a function that I can pass all this information to and return the necessary information when it's finished? All of these conditional statements are inside a loop that could run up to 1000 or so times.
I'm not sure if the cost of preparing the stack frame(?) by jumping into another function is more costly over 1000 iterations to be worth having ~15 lines of duplicated code. Obviously function-alizing it would make it more readable, however this is very specific functionality that is not used anywhere else. The function I could write to eliminate the copy/paste mentality would be something like:
function myHelperFunction(someParameter, someOtherParameter) {
// Code line 1
// Code line 2
// Code line 3
return usefulInformation;
}
And then call the function in all those conditional statements as 1 line per conditional statement:
myHelperFunction(myPassedParameter, myOtherPassedParameter);
Essentially turning those 12 lines into 4.
So the question - is this a good practice in general, to create a new function for a very small amount of code to save some space and readability? Or is the cost for jumping functions too impacting to be worth it? Should one always create a new function for any code that they might copy/paste in the future?
PS - I understand that if this bit of code were to be used in different (Classes) or source files that it would be logical to turn it into a function to avoid needing to find all the locations where it was copy/pasted in order to make changes. But I'm talking more or less single-file/single-Class or in-function kind of a dilemma.
Also, feel free to fix my tags/title if I didn't do it correctly. I'm not really sure how to title/tag this post correctly.
The answer to any optimization question that isn't also an algorithms/data structures question is: Profile your code! Only optimize things that show up as problem areas.
Which means you should find out if function call overhead is actually a performance problem in the specific program you're writing. If it is, inline the code. If it isn't, don't. Simple as that.
You're approaching this the wrong way, in my opinion. In the first place, you shouldn't be using multiple (else)ifs that all execute the same code; use one with a compound or precomputed (in this case I recommend precomputed due to all the possible subconditions) condition. Something like this will probably make maintaining the code a lot easier.
function myFunction() {
bool condition = something ||
somethingElse ||
anotherThing ||
theLastThing;
if (condition) {
// Code line 1
// Code line 2
// Code line 3
}
else {
// Not previously used code
}
}
Yes create a function, in general you should follow the DRY principal. Don't Repeat Yourself.
http://en.wikipedia.org/wiki/Don%27t_repeat_yourself
Your stack operations are going to be minimal for something like this. See Imre Kerr's comment on your question.
It's not just for readability. So many reasons. Maintainability is huge. If this code has to change, it will be a pain for someone else to come along and try to figure out every place to change it. It's a lot better to only have to change code in one place.
I don't know if this apply to the example that you provided, but factoring code is not the only reason to write a function, you can also think in term of tests
A function provides a programming unit that can be tested separately.
So it may happen that you decompose a complex operation into several simpler/more elementary units, even if those functions are only called once.
Since you asked the question for a few lines of code, you could ask yourself:
can I reasonnably name this function?( justDoThis should be OK, doThisAndThatAndThenAnotherThing less so)
does it have a reasonnable number of parameters?(I would say two or three)
is it worth testing it as a separate unit?(does it simplify overall testing)
is the code more readable/understandable with such function call or not?(if answer to first two questions is no, it's not necessarily obvious)
This is a wonderful question, and the answer is: It depends.
Personally I would create a function for increased code readability, but If you are looking for efficiency maybe you would want to leave the code copied and pasted.

Is STL empty() threadsafe?

I have multiple threads modifying an stl vector and an stl list.
I want to avoid having to take a lock if the container is empty
Would the following code be threadsafe? What if items was a list or a map?
class A
{
vector<int> items
void DoStuff()
{
if(!items.empty())
{
AquireLock();
DoStuffWithItems();
ReleaseLock();
}
}
}
It depends what you expect. The other answers are right that in general, standard C++ containers are not thread-safe, and furthermore, that in particular your code doesn’t ward against another thread modifying the container between your call to empty and the acquisition of the lock (but this matter is unrelated to the thread safety of vector::empty).
So, to ward off any misunderstandings: Your code does not guarantee items will be non-empty inside the block.
But your code can still be useful, since all you want to do is avoid redundant lock creations. Your code doesn’t give guarantees but it may prevent an unnecessary lock creation. It won’t work in all cases (other threads can still empty the container between your check and the lock) but in some cases. And if all you’re after is an optimization by omitting a redundant lock, then your code accomplishes that goal.
Just make sure that any actual access to the container is protected by locks.
By the way, the above is strictly speaking undefined behaviour: an STL implementation is theoretically allowed to modify mutable members inside the call to empty. This would mean that the apparently harmless (because read-only) call to empty can actually cause a conflict. Unfortunately, you cannot rely on the assumption that read-only calls are safe with STL containers.
In practice, though, I am pretty sure that vector::empty will not modify any members. But already for list::empty I am less sure. If you really want guarantees, then either lock every access or don’t use the STL containers.
There is no thread-safe guaranty on anything in the containers and algorithms of the the STL.
So, No.
Regardless of whether or not empty is thread safe, your code will not, as written, accomplish your goal.
class A
{
vector<int> items
void DoStuff()
{
if(!items.empty())
{
//Another thread deletes items here.
AquireLock();
DoStuffWithItems();
ReleaseLock();
}
}
}
A better solution is to lock every time you work with items (when iterating, getting items, adding items, checking count/emptiness, etc.), thus providing your own thread safety. So, acquire the lock first, then check if the vector is empty.
As it is already answered, the above code is not thread safe and locking is mandatory before actually doing anything with the container.
But the following should have better performance than always locking and I can't think of a reason that it can be unsafe.
The idea here is that locking can be expensive and we are avoiding it, whenever not really needed.
class A
{
vector<int> items;
void DoStuff()
{
if(!items.empty())
{
AquireLock();
if(!items.empty())
{
DoStuffWithItems();
}
ReleaseLock();
}
}
}
STL is not thread safe and empty too. If you want make container safe you must close all its methods by mutex or other sync

Style Question: if block in or around function?

Let's say that I have a function that should only execute if some constant is defined. which of the following would be better
Option 1: wrap all the function calls in an if block:
if(defined('FOO_BAR_ENABLED')) {
foobar();
}
I figure this way the intent is more clear, but it requires checking the constant every time the function is called.
Option 2: check the constant in the function itself:
function foobar() {
if(!defined('FOO_BAR_ENABLED')) {
return;
}
//do stuff
}
This way requires less lines of code, and the constant is sure to get checked. However, I find it confusing to see calls to this function when it's not actually doing anything. Thoughts?
May I suggest renaming the function to FoobarIfEnabled(), then doing the check in the function?
Stealing liberally from a great language-agnostic answer to one of my own questions, when programming we have the following concerns:
Make it correct.
Make it clear.
Make it concise.
Make it fast. ... in that order.
If you do the check outside the function, you might end up missing it in one place. And if you want to change the behavior, you'll have to find all the places it gets called and fix it. That's a maintenance nightmare which violates principle 1. By adding "IfEnabled" or something like that to the name, now it is not just correct but also is clear. How can you beat that?
Performance is not to be worried about unless the final speed is unsatisfactory and you have identified this as the bottleneck (unlikely).
I recommend you follow the link above and read as it was a very useful answer that gave me much to think about.
Option 3:
void maybe_foobar() {
if(defined('FOO_BAR_ENABLED')) really_foobar();
}
void really_foobar() {
// do stuff
}
On a good day I'd think of better names than "maybe" and "really", but it depends what the function does and why it's turn-off-and-onable.
If there is no circumstance under which anyone could validly "do stuff" when FOO_BAR_ENABLED isn't defined, then I'd go with your option 2 (and perhaps call the function do_stuff_if_possible rather than foobar, if the name foobar was causing confusion as to whether calling it entails actually doing anything). If it's always valid to "do stuff", but some users just so happen do so conditionally, then I'd go with my option 3.
Option 1 is going to result in you copy-and-pasting code around, which is almost always a Bad Sign.
[Edit: here's Option 4, which I suspect is over-engineering, but you never know:
void if_enabled(string str, function f) {
if (defined(str + '_ENABLED')) f();
}
Then you call it with:
if_enabled('FOO_BAR', foobar);
Obviously there's some issues there to do with how your language handles functions, and whether there's any way to pass arbitrary parameters and a return value through if_enabled.]
Does the condition of the if fall within the function's responsibility? Is there a use case for calling the function without the if?
If the condition always needs to be checked, I'd put it in the function. Follow the DRY principle here: Don't Repeat Yourself. Another quip that might be helpful is the SRP - the Single Responsibility Principle - do one thing, and do it well.
In the header file, if foobar always takes the same number of arguments,
#ifdef ENABLE_FOOBAR
#define maybe_foobar(x) foobar(x)
#else
#define maybe_foobar(x)
#endif
Not sure how to do that in C++ or older C dialects if foobar can take a variable number of arguments.
(Just noticed language-agnostic tag. Well, the above technique is what I'd suggest in languages where it works; maybe use an inline function for languages which have those but lack macros).
Option 2, less code and it ensures the constant is defined, as you suggested.
Since this is apparently only used with the foobar() function, then option 2 should be your choice. That means the test is located in only one place and your code is more readable.

Successive success checks

Most of you have probably bumped into a situation, where multiple things must be in check and in certain order before the application can proceed, for example in a very simple case of creating a listening socket (socket, bind, listen, accept etc.). There are at least two obvious ways (don't take this 100% verbatim):
if (1st_ok)
{
if (2nd_ok)
{
...
or
if (!1st_ok)
{
return;
}
if (!2nd_ok)
{
return;
}
...
Have you ever though of anything smarter, do you prefer one over the other of the above, or do you (if the language provides for it) use exceptions?
I prefer the second technique. The main problem with the first one is that it increases the nesting depth of the code, which is a significant issue when you've got a substantial number of preconditions/resource-allocs to check since the business part of the function ends up deeply buried behind a wall of conditions (and frequently loops too). In the second case, you can simplify the conceptual logic to "we've got here and everything's OK", which is much easier to work with. Keeping the normal case as straight-line as possible is just easier to grok, especially when doing maintenance coding.
It depends on the language - e.g. in C++ you might well use exceptions, while in C you might use one of several strategies:
if/else blocks
goto (one of the few cases where a single goto label for "exception" handling might be justified
use break within a do { ... } while (0) loop
Personally I don't like multiple return statements in a function - I prefer to have a common clean up block at the end of the function followed by a single return statement.
This tends to be a matter of style. Some people only like returning at the end of a procedure, others prefer to do it wherever needed.
I'm a fan of the second method, as it allows for clean and concise code as well as ease of adding documentation on what it's doing.
// Checking for llama integration
if (!1st_ok)
{
return;
}
// Llama found, loading spitting capacity
if (!2nd_ok)
{
return;
}
// Etc.
I prefer the second version.
In the normal case, all code between the checks executes sequentially, so I like to see them at the same level. Normally none of the if branches are executed, so I want them to be as unobtrusive as possible.
I use 2nd because I think It reads better and easier to follow the logic. Also they say exceptions should not be used for flow control, but for the exceptional and unexpected cases. Id like to see what pros say about this.
What about
if (1st_ok && 2nd_ok) { }
or if some work must be done, like in your example with sockets
if (1st_ok() && 2nd_ok()) { }
I avoid the first solution because of nesting.
I avoid the second solution because of corporate coding rules which forbid multiple return in a function body.
Of course coding rules also forbid goto.
My workaround is to use a local variable:
bool isFailed = false; // or whatever is available for bool/true/false
if (!check1) {
log_error();
try_recovery_action();
isFailed = true;
}
if (!isfailed) {
if (!check2) {
log_error();
try_recovery_action();
isFailed = true;
}
}
...
This is not as beautiful as I would like but it is the best I've found to conform to my constraints and to write a readable code.
For what it is worth, here are some of my thoughts and experiences on this question.
Personally, I tend to prefer the second case you outlined. I find it easier to follow (and debug) the code. That is, as the code progresses, it becomes "more correct". In my own experience, this has seemed to be the preferred method.
I don't know how common it is in the field, but I've also seen condition testing written as ...
error = foo1 ();
if ((error == OK) && test1)) {
error = foo2 ();
}
if ((error == OK) && (test2)) {
error = foo3 ();
}
...
return (error);
Although readable (always a plus in my books) and avoiding deep nesting, it always struck me as using a lot of unnecessary testing to achieve those ends.
The first method, I see used less frequently than the second. Of those times, the vast majority of the time was because there was no nice way around it. For the remaining few instances, it was justified on the basis of extracting a little more performance on the success case. The argument was that the processor would predict a forward branch as not taken (corresponding to the else clause). This depended upon several factors including, the architecture, compiler, language, need, .... Obviously most projects (and most aspects of the project) did not meet those requirements.
Hope this helps.

Should a function have only one return statement?

Locked. This question and its answers are locked because the question is off-topic but has historical significance. It is not currently accepting new answers or interactions.
Are there good reasons why it's a better practice to have only one return statement in a function?
Or is it okay to return from a function as soon as it is logically correct to do so, meaning there may be many return statements in the function?
I often have several statements at the start of a method to return for "easy" situations. For example, this:
public void DoStuff(Foo foo)
{
if (foo != null)
{
...
}
}
... can be made more readable (IMHO) like this:
public void DoStuff(Foo foo)
{
if (foo == null) return;
...
}
So yes, I think it's fine to have multiple "exit points" from a function/method.
Nobody has mentioned or quoted Code Complete so I'll do it.
17.1 return
Minimize the number of returns in each routine. It's harder to understand a routine if, reading it at the bottom, you're unaware of the possibility that it returned somewhere above.
Use a return when it enhances readability. In certain routines, once you know the answer, you want to return it to the calling routine immediately. If the routine is defined in such a way that it doesn't require any cleanup, not returning immediately means that you have to write more code.
I would say it would be incredibly unwise to decide arbitrarily against multiple exit points as I have found the technique to be useful in practice over and over again, in fact I have often refactored existing code to multiple exit points for clarity. We can compare the two approaches thus:-
string fooBar(string s, int? i) {
string ret = "";
if(!string.IsNullOrEmpty(s) && i != null) {
var res = someFunction(s, i);
bool passed = true;
foreach(var r in res) {
if(!r.Passed) {
passed = false;
break;
}
}
if(passed) {
// Rest of code...
}
}
return ret;
}
Compare this to the code where multiple exit points are permitted:-
string fooBar(string s, int? i) {
var ret = "";
if(string.IsNullOrEmpty(s) || i == null) return null;
var res = someFunction(s, i);
foreach(var r in res) {
if(!r.Passed) return null;
}
// Rest of code...
return ret;
}
I think the latter is considerably clearer. As far as I can tell the criticism of multiple exit points is a rather archaic point of view these days.
I currently am working on a codebase where two of the people working on it blindly subscribe to the "single point of exit" theory and I can tell you that from experience, it's a horrible horrible practice. It makes code extremely difficult to maintain and I'll show you why.
With the "single point of exit" theory, you inevitably wind up with code that looks like this:
function()
{
HRESULT error = S_OK;
if(SUCCEEDED(Operation1()))
{
if(SUCCEEDED(Operation2()))
{
if(SUCCEEDED(Operation3()))
{
if(SUCCEEDED(Operation4()))
{
}
else
{
error = OPERATION4FAILED;
}
}
else
{
error = OPERATION3FAILED;
}
}
else
{
error = OPERATION2FAILED;
}
}
else
{
error = OPERATION1FAILED;
}
return error;
}
Not only does this make the code very hard to follow, but now say later on you need to go back and add an operation in between 1 and 2. You have to indent just about the entire freaking function, and good luck making sure all of your if/else conditions and braces are matched up properly.
This method makes code maintenance extremely difficult and error prone.
Structured programming says you should only ever have one return statement per function. This is to limit the complexity. Many people such as Martin Fowler argue that it is simpler to write functions with multiple return statements. He presents this argument in the classic refactoring book he wrote. This works well if you follow his other advice and write small functions. I agree with this point of view and only strict structured programming purists adhere to single return statements per function.
As Kent Beck notes when discussing guard clauses in Implementation Patterns making a routine have a single entry and exit point ...
"was to prevent the confusion possible
when jumping into and out of many
locations in the same routine. It made
good sense when applied to FORTRAN or
assembly language programs written
with lots of global data where even
understanding which statements were
executed was hard work ... with small methods and mostly local data, it is needlessly conservative."
I find a function written with guard clauses much easier to follow than one long nested bunch of if then else statements.
In a function that has no side-effects, there's no good reason to have more than a single return and you should write them in a functional style. In a method with side-effects, things are more sequential (time-indexed), so you write in an imperative style, using the return statement as a command to stop executing.
In other words, when possible, favor this style
return a > 0 ?
positively(a):
negatively(a);
over this
if (a > 0)
return positively(a);
else
return negatively(a);
If you find yourself writing several layers of nested conditions, there's probably a way you can refactor that, using predicate list for example. If you find that your ifs and elses are far apart syntactically, you might want to break that down into smaller functions. A conditional block that spans more than a screenful of text is hard to read.
There's no hard and fast rule that applies to every language. Something like having a single return statement won't make your code good. But good code will tend to allow you to write your functions that way.
I've seen it in coding standards for C++ that were a hang-over from C, as if you don't have RAII or other automatic memory management then you have to clean up for each return, which either means cut-and-paste of the clean-up or a goto (logically the same as 'finally' in managed languages), both of which are considered bad form. If your practices are to use smart pointers and collections in C++ or another automatic memory system, then there isn't a strong reason for it, and it become all about readability, and more of a judgement call.
I lean to the idea that return statements in the middle of the function are bad. You can use returns to build a few guard clauses at the top of the function, and of course tell the compiler what to return at the end of the function without issue, but returns in the middle of the function can be easy to miss and can make the function harder to interpret.
Are there good reasons why it's a better practice to have only one return statement in a function?
Yes, there are:
The single exit point gives an excellent place to assert your post-conditions.
Being able to put a debugger breakpoint on the one return at the end of the function is often useful.
Fewer returns means less complexity. Linear code is generally simpler to understand.
If trying to simplify a function to a single return causes complexity, then that's incentive to refactor to smaller, more general, easier-to-understand functions.
If you're in a language without destructors or if you don't use RAII, then a single return reduces the number of places you have to clean up.
Some languages require a single exit point (e.g., Pascal and Eiffel).
The question is often posed as a false dichotomy between multiple returns or deeply nested if statements. There's almost always a third solution which is very linear (no deep nesting) with only a single exit point.
Update: Apparently MISRA guidelines promote single exit, too.
To be clear, I'm not saying it's always wrong to have multiple returns. But given otherwise equivalent solutions, there are lots of good reasons to prefer the one with a single return.
Having a single exit point does provide an advantage in debugging, because it allows you to set a single breakpoint at the end of a function to see what value is actually going to be returned.
In general I try to have only a single exit point from a function. There are times, however, that doing so actually ends up creating a more complex function body than is necessary, in which case it's better to have multiple exit points. It really has to be a "judgement call" based on the resulting complexity, but the goal should be as few exit points as possible without sacrificing complexity and understandability.
No, because we don't live in the 1970s any more. If your function is long enough that multiple returns are a problem, it's too long.
(Quite apart from the fact that any multi-line function in a language with exceptions will have multiple exit points anyway.)
My preference would be for single exit unless it really complicates things. I have found that in some cases, multiple exist points can mask other more significant design problems:
public void DoStuff(Foo foo)
{
if (foo == null) return;
}
On seeing this code, I would immediately ask:
Is 'foo' ever null?
If so, how many clients of 'DoStuff' ever call the function with a null 'foo'?
Depending on the answers to these questions it might be that
the check is pointless as it never is true (ie. it should be an assertion)
the check is very rarely true and so it may be better to change those specific caller functions as they should probably take some other action anyway.
In both of the above cases the code can probably be reworked with an assertion to ensure that 'foo' is never null and the relevant callers changed.
There are two other reasons (specific I think to C++ code) where multiple exists can actually have a negative affect. They are code size, and compiler optimizations.
A non-POD C++ object in scope at the exit of a function will have its destructor called. Where there are several return statements, it may be the case that there are different objects in scope and so the list of destructors to call will be different. The compiler therefore needs to generate code for each return statement:
void foo (int i, int j) {
A a;
if (i > 0) {
B b;
return ; // Call dtor for 'b' followed by 'a'
}
if (i == j) {
C c;
B b;
return ; // Call dtor for 'b', 'c' and then 'a'
}
return 'a' // Call dtor for 'a'
}
If code size is an issue - then this may be something worth avoiding.
The other issue relates to "Named Return Value OptimiZation" (aka Copy Elision, ISO C++ '03 12.8/15). C++ allows an implementation to skip calling the copy constructor if it can:
A foo () {
A a1;
// do something
return a1;
}
void bar () {
A a2 ( foo() );
}
Just taking the code as is, the object 'a1' is constructed in 'foo' and then its copy construct will be called to construct 'a2'. However, copy elision allows the compiler to construct 'a1' in the same place on the stack as 'a2'. There is therefore no need to "copy" the object when the function returns.
Multiple exit points complicates the work of the compiler in trying to detect this, and at least for a relatively recent version of VC++ the optimization did not take place where the function body had multiple returns. See Named Return Value Optimization in Visual C++ 2005 for more details.
Having a single exit point reduces Cyclomatic Complexity and therefore, in theory, reduces the probability that you will introduce bugs into your code when you change it. Practice however, tends to suggest that a more pragmatic approach is needed. I therefore tend to aim to have a single exit point, but allow my code to have several if that is more readable.
I force myself to use only one return statement, as it will in a sense generate code smell. Let me explain:
function isCorrect($param1, $param2, $param3) {
$toret = false;
if ($param1 != $param2) {
if ($param1 == ($param3 * 2)) {
if ($param2 == ($param3 / 3)) {
$toret = true;
} else {
$error = 'Error 3';
}
} else {
$error = 'Error 2';
}
} else {
$error = 'Error 1';
}
return $toret;
}
(The conditions are arbritary...)
The more conditions, the larger the function gets, the more difficult it is to read. So if you're attuned to the code smell, you'll realise it, and want to refactor the code. Two possible solutions are:
Multiple returns
Refactoring into separate functions
Multiple Returns
function isCorrect($param1, $param2, $param3) {
if ($param1 == $param2) { $error = 'Error 1'; return false; }
if ($param1 != ($param3 * 2)) { $error = 'Error 2'; return false; }
if ($param2 != ($param3 / 3)) { $error = 'Error 3'; return false; }
return true;
}
Separate Functions
function isEqual($param1, $param2) {
return $param1 == $param2;
}
function isDouble($param1, $param2) {
return $param1 == ($param2 * 2);
}
function isThird($param1, $param2) {
return $param1 == ($param2 / 3);
}
function isCorrect($param1, $param2, $param3) {
return !isEqual($param1, $param2)
&& isDouble($param1, $param3)
&& isThird($param2, $param3);
}
Granted, it is longer and a bit messy, but in the process of refactoring the function this way, we've
created a number of reusable functions,
made the function more human readable, and
the focus of the functions is on why the values are correct.
I would say you should have as many as required, or any that make the code cleaner (such as guard clauses).
I have personally never heard/seen any "best practices" say that you should have only one return statement.
For the most part, I tend to exit a function as soon as possible based on a logic path (guard clauses are an excellent example of this).
I believe that multiple returns are usually good (in the code that I write in C#). The single-return style is a holdover from C. But you probably aren't coding in C.
There is no law requiring only one exit point for a method in all programming languages. Some people insist on the superiority of this style, and sometimes they elevate it to a "rule" or "law" but this belief is not backed up by any evidence or research.
More than one return style may be a bad habit in C code, where resources have to be explicitly de-allocated, but languages such as Java, C#, Python or JavaScript that have constructs such as automatic garbage collection and try..finally blocks (and using blocks in C#), and this argument does not apply - in these languages, it is very uncommon to need centralised manual resource deallocation.
There are cases where a single return is more readable, and cases where it isn't. See if it reduces the number of lines of code, makes the logic clearer or reduces the number of braces and indents or temporary variables.
Therefore, use as many returns as suits your artistic sensibilities, because it is a layout and readability issue, not a technical one.
I have talked about this at greater length on my blog.
There are good things to say about having a single exit-point, just as there are bad things to say about the inevitable "arrow" programming that results.
If using multiple exit points during input validation or resource allocation, I try to put all the 'error-exits' very visibly at the top of the function.
Both the Spartan Programming article of the "SSDSLPedia" and the single function exit point article of the "Portland Pattern Repository's Wiki" have some insightful arguments around this. Also, of course, there is this post to consider.
If you really want a single exit-point (in any non-exception-enabled language) for example in order to release resources in one single place, I find the careful application of goto to be good; see for example this rather contrived example (compressed to save screen real-estate):
int f(int y) {
int value = -1;
void *data = NULL;
if (y < 0)
goto clean;
if ((data = malloc(123)) == NULL)
goto clean;
/* More code */
value = 1;
clean:
free(data);
return value;
}
Personally I, in general, dislike arrow programming more than I dislike multiple exit-points, although both are useful when applied correctly. The best, of course, is to structure your program to require neither. Breaking down your function into multiple chunks usually help :)
Although when doing so, I find I end up with multiple exit points anyway as in this example, where some larger function has been broken down into several smaller functions:
int g(int y) {
value = 0;
if ((value = g0(y, value)) == -1)
return -1;
if ((value = g1(y, value)) == -1)
return -1;
return g2(y, value);
}
Depending on the project or coding guidelines, most of the boiler-plate code could be replaced by macros. As a side note, breaking it down this way makes the functions g0, g1 ,g2 very easy to test individually.
Obviously, in an OO and exception-enabled language, I wouldn't use if-statements like that (or at all, if I could get away with it with little enough effort), and the code would be much more plain. And non-arrowy. And most of the non-final returns would probably be exceptions.
In short;
Few returns are better than many returns
More than one return is better than huge arrows, and guard clauses are generally ok.
Exceptions could/should probably replace most 'guard clauses' when possible.
You know the adage - beauty is in the eyes of the beholder.
Some people swear by NetBeans and some by IntelliJ IDEA, some by Python and some by PHP.
In some shops you could lose your job if you insist on doing this:
public void hello()
{
if (....)
{
....
}
}
The question is all about visibility and maintainability.
I am addicted to using boolean algebra to reduce and simplify logic and use of state machines. However, there were past colleagues who believed my employ of "mathematical techniques" in coding is unsuitable, because it would not be visible and maintainable. And that would be a bad practice. Sorry people, the techniques I employ is very visible and maintainable to me - because when I return to the code six months later, I would understand the code clearly rather seeing a mess of proverbial spaghetti.
Hey buddy (like a former client used to say) do what you want as long as you know how to fix it when I need you to fix it.
I remember 20 years ago, a colleague of mine was fired for employing what today would be called agile development strategy. He had a meticulous incremental plan. But his manager was yelling at him "You can't incrementally release features to users! You must stick with the waterfall." His response to the manager was that incremental development would be more precise to customer's needs. He believed in developing for the customers needs, but the manager believed in coding to "customer's requirement".
We are frequently guilty for breaking data normalization, MVP and MVC boundaries. We inline instead of constructing a function. We take shortcuts.
Personally, I believe that PHP is bad practice, but what do I know. All the theoretical arguments boils down to trying fulfill one set of rules
quality = precision, maintainability
and profitability.
All other rules fade into the background. And of course this rule never fades:
Laziness is the virtue of a good
programmer.
I lean towards using guard clauses to return early and otherwise exit at the end of a method. The single entry and exit rule has historical significance and was particularly helpful when dealing with legacy code that ran to 10 A4 pages for a single C++ method with multiple returns (and many defects). More recently, accepted good practice is to keep methods small which makes multiple exits less of an impedance to understanding. In the following Kronoz example copied from above, the question is what occurs in //Rest of code...?:
void string fooBar(string s, int? i) {
if(string.IsNullOrEmpty(s) || i == null) return null;
var res = someFunction(s, i);
foreach(var r in res) {
if(!r.Passed) return null;
}
// Rest of code...
return ret;
}
I realise the example is somewhat contrived but I would be tempted to refactor the foreach loop into a LINQ statement that could then be considered a guard clause. Again, in a contrived example the intent of the code isn't apparent and someFunction() may have some other side effect or the result may be used in the // Rest of code....
if (string.IsNullOrEmpty(s) || i == null) return null;
if (someFunction(s, i).Any(r => !r.Passed)) return null;
Giving the following refactored function:
void string fooBar(string s, int? i) {
if (string.IsNullOrEmpty(s) || i == null) return null;
if (someFunction(s, i).Any(r => !r.Passed)) return null;
// Rest of code...
return ret;
}
One good reason I can think of is for code maintenance: you have a single point of exit. If you want to change the format of the result,..., it's just much simpler to implement. Also, for debugging, you can just stick a breakpoint there :)
Having said that, I once had to work in a library where the coding standards imposed 'one return statement per function', and I found it pretty tough. I write lots of numerical computations code, and there often are 'special cases', so the code ended up being quite hard to follow...
Multiple exit points are fine for small enough functions -- that is, a function that can be viewed on one screen length on its entirety. If a lengthy function likewise includes multiple exit points, it's a sign that the function can be chopped up further.
That said I avoid multiple-exit functions unless absolutely necessary. I have felt pain of bugs that are due to some stray return in some obscure line in more complex functions.
I've worked with terrible coding standards that forced a single exit path on you and the result is nearly always unstructured spaghetti if the function is anything but trivial -- you end up with lots of breaks and continues that just get in the way.
Single exit point - all other things equal - makes code significantly more readable.
But there's a catch: popular construction
resulttype res;
if if if...
return res;
is a fake, "res=" is not much better than "return". It has single return statement, but multiple points where function actually ends.
If you have function with multiple returns (or "res="s), it's often a good idea to break it into several smaller functions with single exit point.
My usual policy is to have only one return statement at the end of a function unless the complexity of the code is greatly reduced by adding more. In fact, I'm rather a fan of Eiffel, which enforces the only one return rule by having no return statement (there's just a auto-created 'result' variable to put your result in).
There certainly are cases where code can be made clearer with multiple returns than the obvious version without them would be. One could argue that more rework is needed if you have a function that is too complex to be understandable without multiple return statements, but sometimes it's good to be pragmatic about such things.
If you end up with more than a few returns there may be something wrong with your code. Otherwise I would agree that sometimes it is nice to be able to return from multiple places in a subroutine, especially when it make the code cleaner.
Perl 6: Bad Example
sub Int_to_String( Int i ){
given( i ){
when 0 { return "zero" }
when 1 { return "one" }
when 2 { return "two" }
when 3 { return "three" }
when 4 { return "four" }
...
default { return undef }
}
}
would be better written like this
Perl 6: Good Example
#Int_to_String = qw{
zero
one
two
three
four
...
}
sub Int_to_String( Int i ){
return undef if i < 0;
return undef unless i < #Int_to_String.length;
return #Int_to_String[i]
}
Note this is was just a quick example
I vote for Single return at the end as a guideline. This helps a common code clean-up handling ... For example, take a look at the following code ...
void ProcessMyFile (char *szFileName)
{
FILE *fp = NULL;
char *pbyBuffer = NULL:
do {
fp = fopen (szFileName, "r");
if (NULL == fp) {
break;
}
pbyBuffer = malloc (__SOME__SIZE___);
if (NULL == pbyBuffer) {
break;
}
/*** Do some processing with file ***/
} while (0);
if (pbyBuffer) {
free (pbyBuffer);
}
if (fp) {
fclose (fp);
}
}
This is probably an unusual perspective, but I think that anyone who believes that multiple return statements are to be favoured has never had to use a debugger on a microprocessor that supports only 4 hardware breakpoints. ;-)
While the issues of "arrow code" are completely correct, one issue that seems to go away when using multiple return statements is in the situation where you are using a debugger. You have no convenient catch-all position to put a breakpoint to guarantee that you're going to see the exit and hence the return condition.
The more return statements you have in a function, the higher complexity in that one method. If you find yourself wondering if you have too many return statements, you might want to ask yourself if you have too many lines of code in that function.
But, not, there is nothing wrong with one/many return statements. In some languages, it is a better practice (C++) than in others (C).