Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I often talk to Java programmers who say "Don't put multiple return statements in the same method." When I ask them to tell me the reasons why, all I get is "The coding standard says so." or "It's confusing." When they show me solutions with a single return statement, the code looks uglier to me. For example:

if (blablabla)
   return 42;
else
   return 97;

"This is ugly, you have to use a local variable!"

int result;
if (blablabla)
   result = 42;
else
   result = 97;
return result;

How does this 50% code bloat make the program any easier to understand? Personally, I find it harder, because the state space has just increased by another variable that could easily have been prevented.

Of course, normally I would just write:

return (blablabla) ? 42 : 97;

But the conditional operator gets even less love among Java programmers. "It's incomprehensible!"

Where did this notion of "one return only" come from, and why do people adhere to it rigidly?

share|improve this question
27  
Concerning the ternary operations, there was a similar topic on Programmers before. Developers should evolve along with the languages they are using. –  Steven Jeuris Nov 9 '11 at 11:53
5  
@StevenJeuris Because this question has wound up getting the best answers—by far—of the three, we opted to dupe the older ones (which were really not constructive) to this question. Note this has also come up on Stack Overflow several times: 1, 2, 3, and 4. –  user8 Nov 10 '11 at 1:59
3  
Your initial code can be even simpler: if (blablabla) return 42; return 97; –  Kyralessa Nov 10 '11 at 5:17
6  
Rule of thumb loosening the topic rule: return can occur multiple times but only within first 5 (uninitialized/unnecessary/sanity check fail) and last 10 (pick various outcomes) lines of a function. Generally, a very early return is preferred to enclosing whole body in an if(). –  SF. Nov 10 '11 at 8:06
3  
@SF, if your function is more than 10 lines, IT'S TOO BIG! –  Rob K Sep 19 '12 at 20:39

21 Answers 21

This notion of Single Entry, Single Exit (SESE) comes from languages with explicit resource management, like C and assembly. In C, code like this will leak resources:

void f()
{
  resource res = acquire_resource();  // think malloc()
  if( f1(res) )
    return; // leaks res
  f2(res);
  release_resource(res);  // think free()
}

In such languages, you basically have three options:

  • Replicate the cleanup code.
    Ugh. Redundancy is always bad.

  • Use a goto to jump to the cleanup code.
    This requires the cleanup code to be the last thing in the function. (And this is why some argue that goto has its place. And it has indeed – in C.)

  • Introduce a local variable and manipulate control flow through that.
    The disadvantage is that control flow manipulated through syntax (think break, return, if, while) is much easier to follow than control flow manipulated through the state of variables (because those variables have no state when you look at the algorithm).

In assembly it's even weirder, because you can jump to any address in a function when you call that function, which effectively means you have an almost unlimited number of entry points to any function. (Sometimes this is helpful. Such thunks are a common technique for compilers to implement the this pointer adjustment necessary for calling virtual functions in multiple-inheritance scenarios in C++.)

When you have to manage resources manually, exploiting the options of entering or exiting a function anywhere leads to more complex code, and thus to bugs. Therefore, a school of thought appeared that propagated SESE, in order to get cleaner code and less bugs.


However, when a language features exceptions, (almost) any function might be exited prematurely at (almost) any point, so you need to make provisions for premature return anyway. (I think finally is mainly used for that in Java and using (when implementing IDisposable... finally otherwise) in C#; C++ instead employs RAII.) Once you have done this, you cannot fail to clean up after yourself due to an early return statement, so what is probably the strongest argument in favor of SESE has vanished.

That leaves readability. Of course, a 200 LoC function with half a dozen return statements sprinkled randomly over it is not good programming style and does not make for readable code. But such a function wouldn't be easy to understand without those premature returns either.

So in languages where resources are not or should not be managed manually, there is little or no value in adhering to the old SESE convention. OTOH, as I have argued above, SESE often makes code more complex. So it is a dinosaur that (except for C) does not fit well into most of today's languages. Instead of helping the understandability of code, it hinders it.


So why do Java programmers stick to this? I don't know, but from my (outside) POV, Java took a lot of conventions from C (where they make sense) and applied them to its OO world (where they are useless or outrightly bad), where it now sticks to them, no matter what the costs. (Like the convention to define all your variables at the beginning of the scope.)

But programmers stick to all kinds of strange notations for irrational reasons. (Deeply nested structural statements – "arrowheads" – were, in languages like Pascal, once seen as beautiful code.) Applying pure logical reasoning to this seems to fail to convince the majority of them to deviate from their established ways. So the best way to change such habits is probably to teach them early on to do what's best, not what's conventional. You, being a programming teacher, have it in your hand. :)

share|improve this answer
33  
Right. In Java, cleanup code belongs in finally clauses where it gets executed regardless of early returns or exceptions. –  dan04 Nov 9 '11 at 9:41
11  
@dan04 in Java 7 you don't even need the finally most of the time. –  R. Martinho Fernandes Nov 9 '11 at 9:45
58  
@Steven: Of course you can demonstrate that! In fact, you can show convoluted and complex code with any feature that can also be shown to make code simpler and easier to understand. Everything can be abused. The point is to write code so that it is easier to understand, and when that involves throwing SESE out the window, so be it, and damn the old habits that applied to different languages. But I wouldn't hesitate to control execution by variables either if I'd think it made the code easier to read. It's just that I cannot remember having seen such code in almost two decades. –  sbi Nov 9 '11 at 12:31
11  
@Karl: Indeed, it is a severe shortcoming of GC languages like Java that they relieve you from having to clean up one resource, but fail with all the others. (C++ solves this problem for all resources using RAII.) But I wasn't even talking of only memory (I only put malloc() and free() into a comment as an example), I was talking about resources in general. I also wasn't implying GC would solve these problems. (I did mention C++, which doesn't have GC out of the box.) From what I understand, in Java finally is used to solve this problem. –  sbi Nov 9 '11 at 14:15
7  
@sbi: More important for a function (procedure, method, etc.) than being no more than a page long is for the function to have a clearly defined contract; if it's not doing something clear because it's been chopped up to satisfy an arbitrary length constraint, that's Bad. Programming is about playing off different, sometimes conflicting forces against each other. –  Donal Fellows Nov 22 '11 at 14:20

This is somewhat connected to Guard Clause refactoring.

http://stackoverflow.com/a/8493256/679340

Guard Clause will add returns to the beginning of your methods. And it makes code a lot cleaner in my opinion.

share|improve this answer

It's always easy to link Fowler.

One of the main examples that go against SESE are guard clauses:

Replace Nested Conditional with Guard Clauses

Use Guard Clauses for all the special cases

double getPayAmount() {
    double result;
    if (_isDead) result = deadAmount();
    else {
        if (_isSeparated) result = separatedAmount();
        else {
            if (_isRetired) result = retiredAmount();
            else result = normalPayAmount();
        };
    }
return result;
};  

                                                                                                         http://www.refactoring.com/catalog/arrow.gif

double getPayAmount() {
    if (_isDead) return deadAmount();
    if (_isSeparated) return separatedAmount();
    if (_isRetired) return retiredAmount();
    return normalPayAmount();
};  

For more inforamtion see page 250 of Refactoring...

share|improve this answer

While I agree that single point of exit is sort of ridiculous in Java there is some merit to making sure all conditions are met and not exiting prematurely. In functional programming this far easier as the languages including the control constructs are generally expression based. That is the expression always exits to one value.

Unfortunately Java is not expression based but you can simulate it by using local final variables:

final String something;
switch (...) {
// switch has to set something
}

Consequently this is a bad single point of exit that I see often just to avoid typing else:

String s = "default";
if (blah) 
    s = "something";
return s;

While the code above seems OK it can get confusing if you add to the method.

final String s;
if (blah) {
    s = "something";
}
else {
    s = "default";
}
return s;

The above is better but obviously better is just to return in each branch (ie no local variable s.):

if (blah) {
    return "something";
}
else {
    return "default";
}

The other nice thing about expression based variable setting is that its generally easier to refactor as most IDEs allow you to extract methods from control statements. Using final makes this much easier to guarantee.

My point is its far better to write your code to be expression based instead of focusing on single point of exit.

share|improve this answer

There are three reasons why I consider early return code to be better in general.

  1. Why carry on when you know the answer? You are also forcing readers to follow the entire function just in case the result variable gets modified down the line.
  2. It makes exit conditions clear. You immediately define the contract of your function, stating what kind of input will make the function give useful output. This is only useful if you define your exit conditions in the beginning of the function, wich is preferable anyway.
  3. There is no need to write extra code to dodge further modification to the result. No need to pepper a function with "else if" clauses or wrap large sections of code in if statemetns just because the first condition has already calculated the result. This minimizes nesting and complexity.

There is only one catch, and that is that really long functions and randomly placed exit conditions are a pain to work with, but the long function is the culprit, not the early return.

share|improve this answer

In theory a single exit point sounds great. In complex coding it is not. Consider this case:

if (condition1)
   don'tcontinue1 
else 
   do elsethings1
endif
//condition2 check
if (condition2)
   don'tcontinue2  
else    
   do elsethings2
endif
//conditionN check...

if you have 5 conditions, and you want to use a single exit you either have to:

A-Nest the if statements

B-Introduce a flag

C-Write 1 complex if upfront

D-Use a goto as a single exit point

All of the above don't lead to better code (except for (D), more is on an early paper found here: GOTO Considered Harmful)

Early exit is not as harmful as it looks unless it has side effects. An example of side effect is not cleaning up or releasing resources. For example this is harmful:

myConnection.Open();
If condition1
   return
else
   do things
endif
myconnection.Close();

In the above case, the connection will not be closed in case condition1 is true, which is a bad thing.

So in my opinion, it is not that bad to use early exits as long as the practice is used with care.

share|improve this answer
1  
Depending on the criteria in question, writing one large if statement up front might not even be a realistic option at all. –  Michael Kjörling Nov 9 '11 at 12:21
46  
If you find yourself writing code like this, you need to take a big step back and ask "Am I trying to do too much in this one module? Have I thought this through?" With 5 conditions in one module, you may have as many as 32 discrete paths through the code (2^5), each and every one of which must be thoroughly tested. (This is the basic observation behind McCabe's cyclomatic complexity metric: the more paths through the code, the harder it is to test.) –  John R. Strohm Nov 9 '11 at 13:50
7  
This is a good answer, this is the conclusion anyone with real world experience comes up with eventually. Just one return statement sounds ideal. But if it makes the code more complex, then it is just plain stupid. If you have ever written any form of parser, you'll know that returning instantly upon error gives far cleaner code than some abomination like if(flag){ if(flag){ if(flag){. The very same thing applies when writing embedded data protocol decoders, where real time demands make it impossible to have just one return statement: you should return immediately upon error. –  user29079 Nov 9 '11 at 16:11
6  
John R. Strohm: It is very easy to say that every function should be kept at a minimum, in theoretic utopia. In reality, there are plenty of reasons why you might end up writing complex code like this. State machines, parsers, protocol encoders/decoders, complex hardware register handling, limited alternatives in the system (example: Win API winproc) etc etc. –  user29079 Nov 9 '11 at 16:17
1  
@JohnR.Strohm, thanks for you comments. You are correct about the complexity issue but this kind of code is faced with many applications such as input data validation for forms. Most forms include different objects and it is sometimes natural to invoke the form validation in one method (of course one could use methods in each class) but the utilization of those methods is usually placed in 1 method usually placed at the client. –  Emmad Kareem Nov 9 '11 at 16:21

From a C# perspective...

I had an instance recently in an environment where many people are changing code, and checking in and out of source control.

I had a file checked out, with an if statement that set two properties of an object if both values were not null.

if (value1 != null && value2 != null) {
    object.Value1 = value1;
    object.Value2 = value2;
}

I added some code south of the if statement, to set some further properties.

if (value1 != null && value2 != null) {
    object.Value1 = value1;
    object.Value2 = value2;
}

object.Value3 = "This is necessary.";

Meanwhile, someone else picked up their refactoring tool and went through all the warnings about indented code. They allowed their tool to "invert if to reduce nesting". The if statement then returned if either of the values was null.

if (value1 == null || value2 == null)
    return;

object.Value1 = value1;
object.Value2 = value2;

Then I merged this new code in.

if (value1 == null || value2 == null)
    return;

object.Value1 = value1;
object.Value2 = value2;

object.Value3 = "This is necessary.";

The upshot is that if value1 or value2 are null, object.Value3 will never be set, and suddenly loads of unit tests fail. More work for me.

That's why I encourage people not to return from inside if blocks.

If there is a validation issue, e.g.

public void MyMethod(MyObject object) {
    if (object == null)
        {
            // invalid state
        }

    ...

}

then I would recommend throwing an exception, rather than simply returning (or returning a default value)

share|improve this answer

There is a case where one return only isn't comfortable. For example when you catch an error or extraordinary case, and should immediately return. For example:

function some_fun( a ) {
    if ( !a ) { result = false; } 

    var result;

    // some big piece of code
    // with many levels of indention
    // and so on
    if ( /*  */ ) {
        // some code
        result = 1;
    } else {
        result = 2;
    }

    return result;
}

I think it's much prettier than such an example:

function some_fun( a ) {
    var result;

    if ( !a ) {
        result = false;
    } else {
        // some big piece of code
        // with many levels of indention
        // and so on
        if ( /*  */ ) {
            // some code
            result = 1;
        } else {
            result = 2;
        }
    }

    return result;
}

So there is one more indention level...

share|improve this answer

Just because a feature is available in a programming language, doesn't means it suits your programming needs. This topic is one of the reasons I prefer (structured or object oriented) pascal over c style programming languages.

(* structured or object pascal*)
function test(var x: integer): integer;
begin
  // result is automatically declared      

  if (x > 0)
  begin
    Result := DoSomething(x);
  end
  else
  begin
    Result := DoSomethingElse(x);
  end;

  // can debug here, with code or Debugger Tool
  // WriteLn("Result: ", Result);
end;

/* c, c++, or similar */
int test(int x)
{

  if (x > 0)
  {
    return DoSomething(x);
  }
  else
  {
    return DoSomethingElse(x);
  }

  // cannot know the value of the result
}

Since I have to use a lot of c style programming languages at work, I use this trick, which It ca be debug easily.

int test(int x)
{
  // copied from pascal
  int Result = 0;

  if (x > 0)
  {
    Result = DoSomething(x);
  }
  else
  {
    Result = DoSomethingElse(x);
  }

  // can debug here, with code or Debugger Tool
  // cout << "Result: " << Result << "\n"

  return Result;
}    

Cheers.

share|improve this answer
1  
Nonsense. A competent debugging program will be able to display the return value anyway. –  Konrad Rudolph Nov 11 '11 at 11:23
1  
@Konrad Rudolph Work with several IDE / Debugger tools. Its easier to store the result in a temporal variable, and then, let the tool display the contents of the variable, before exit the (global) function or (class function) method... –  umlcat Nov 11 '11 at 18:59

Multiple returns can also be more efficient. If you have a code that checks for something and is ready to return before going through the rest of the operations, then why introduce a second variable to track its state?

for example:

function doStuff(variable) {
    if (variable == 5)
       return true;


    for(var i = 0, ret = 0; i < variable; i++){
       ret += variable;
    }
    if (ret == 5)
       return true;

    //do 10 more operations
}

This is faster then putting the extra check to see if you need to continue with the operation or not like in this example:

function doStuff(variable) {
    var value = true;
    var done = false;

    if (variable == 5) {
       value = true;
       done = true;
    }

    if (!done){

       for(var i = 0, ret = 0; i < variable; i++){
          ret += variable;
       }
       done = ret == 5;
       value = ret == 5;  
    }
    if (!done){
       //do 10 more operations
    }

    return value;
}

From the above 2 examples, which is easier to read and understand? Not only is the first one easier to understand, it also avoids the multiple of extra checks required by the second example.

Of course this is sometimes still required for cleanup code, however why not simply put that in a different method all together?

share|improve this answer

Consider the fact that multiple return statements are equivalent to having GOTO's to a single return statement. This is the same case with break statements. As thus, some, like me, consider them GOTO's for all intents and purposes.

However, I don't consider these types of GOTO's harmful and will not hesitate to use an actual GOTO in my code if I find a good reason for it.

My general rule is that GOTO's are for flow control only. They should never be used for any looping, and you should never GOTO 'upwards' or 'backwards'. (which is how breaks/returns work)

As others have mentioned, the following is a must read GOTO Statement Considered Harmful
However, keep in mind that this was written in 1970 when GOTO's were way overused. Not every GOTO is harmful and I would not discourage their use as long as you don't use them instead of normal constructs, but rather in the odd case that using normal constructs would be highly inconvenient.

I find that using them in error cases where you need to escape an area because of a failure that should never occur in normal cases useful at times. But you should also consider putting this code into a separate function so that you can just return early instead of using a GOTO... but sometimes that's also inconvenient.

share|improve this answer
1  
All structured constructs that replace gotos are implemented in terms of goto. E.g. loops, "if" and "case". This does not make them bad - in fact the opposite. Also, it is "intents and purposes". –  Anthony Nov 10 '11 at 15:05

I wrote a blog post on this topic a while back.

The bottom line is that this rule comes from the age of languages that don't have garbage collection or exception handling. There is no formal study that shows that this rule leads to better code in modern languages. Feel free to ignore it whenever this will lead to shorter or more readable code. The Java guys insisting on this are blindly and unquestioning following a outdated, pointless rule.

This question has also been asked on Stackoverflow

share|improve this answer

One reason to use only one exit point at the end of the function is that indentation always has the same meaning. This helps make reading code faster and less error prone.

A new style for every language seems to make sense though. Take the following Ruby code:

def get_new_animal_action(animal)
  if animal.type == :cat
    if distance_from_home(animal.address) > DRIVE_LIMIT
      :buy_shipping_container
    else
      :drive_animal_home
    end
  else
    :call_bob
  end
end

Since the 'if' statements act like functions with a return value, we have the clarity of C with a single exit point and the lightness of multiple returns.

share|improve this answer
1  
Deep nested control structures are aften a call for additional abstractions in the for of pulling functionality out into other functions. –  Sean Vikoren Nov 10 '11 at 14:40

There is a factor often overlooked in this discussion and that is the future of the code.

In most commercial code, one person writes it, possibly dozens of people enhance it over a period of perhaps several years and then one person has the job of debugging it by which time it is as snarled up as it possibly can be.

So take your two pieces of code, one single-exit and one multi-exit and add some real bulk to each one but maintain the exitedness of each. Now tell me how valuable the code is! I can guarantee the single-exit code will still be single-exit and simple to the point of trivial to trace while the other will have cost many hours of debugging.

I do not object to early-exiting when parameter and state checking so long as it is both early and cheap. There are also times when I will code a multi-exit method because that is what it truly is but I will never create a multi-exit method just because it is quicker to write or slightly shorter.

Imagine yourself still in the same company ten years down the line and a junior programmer comes to you, shows you your own code and asks you why it is so complex. You can either blame all those other juniors who have modified it to death or take responsibility for your own short-cut.

share|improve this answer
1  
Bulky enhancements should probably not go in such a function anyway. Where they become necessary, it would then be better to make both the old version and the new bulky stuff auxiliary functions of the method itself. –  leftaroundabout Nov 11 '11 at 21:42
1  
re: "single-exit will be trivial to trace". Only if you ignore the reams of nested if-checks and methods that cover multiple screens to view. –  Dunk Oct 4 '13 at 12:56

"Single Entry, Single Exit" was written when most programming was done in assembly language, FORTRAN, or COBOL. It has been widely misinterpreted, because modern languages do not support the practices Dijkstra was warning against.

"Single Entry" meant "do not create alternate entry points for functions". In assembly language, of course, it is possible to enter a function at any instruction. FORTRAN supported multiple entries to functions with the ENTRY statement:

      SUBROUTINE S(X, Y)
      R = SQRT(X*X + Y*Y)
C ALTERNATE ENTRY USED WHEN R IS ALREADY KNOWN
      ENTRY S2(R)
      ...
      RETURN
      END

C USAGE
      CALL S(3,4)
C ALTERNATE USAGE
      CALL S2(5)

"Single Exit" meant that a function should only return to one place: the statement immediately following the call. It did not mean that a function should only return from one place. When Structured Programming was written, it was common practice for a function to indicate an error by returning to an alternate location. FORTRAN supported this via "alternate return":

C SUBROUTINE WITH ALTERNATE RETURN.  THE '*' IS A PLACE HOLDER FOR THE ERROR RETURN
      SUBROUTINE QSOLVE(A, B, C, X1, X2, *)
      DISCR = B*B - 4*A*C
C NO SOLUTIONS, RETURN TO ERROR HANDLING LOCATION
      IF DISCR .LT. 0 RETURN 1
      SD = SQRT(DISCR)
      DENOM = 1.0 / (2*A)
      X1 = (-B + SD) / DENOM
      X2 = (-B - SD) / DENOM
      RETURN
      END

C USE OF ALTERNATE RETURN
      CALL QSOLVE(1, 0, 1, X1, X2, *99)
C SOLUTION FOUND
      ...
C QSOLVE RETURNS HERE IF NO SOLUTIONS
99    PRINT 'NO SOLUTIONS'

Both these techniques were highly error prone. Use of alternate entries often left some variable uninitialized. Use of alternate returns had all the problems of a GOTO statement, with the additional complication that the branch condition was not adjacent to the branch, but somewhere in the subroutine.

share|improve this answer
31  
+1, this answer needs some serious up voting. Hoping it'll get a chance to compete at the top. P.s. if it would, be prepared to add some references. ;p –  Steven Jeuris Nov 9 '11 at 23:30
8  
That's indeed interesting histoy, +1 from me. How then got "Single Exit" perverted so badly? –  sbi Nov 10 '11 at 15:13
15  
And don't forget spaghetti code. It was not unknown for subroutines to exit using a GOTO instead of a return, leaving the function call parameters and return address on the stack. Single exit was promoted as a way to at least funnel all the code paths to a RETURN statement. –  TMN Nov 10 '11 at 15:52
3  
@kevin: Yeah, but according to you this doesn't even mean anymore what it was invented as. (BTW, I'm actually reasonably sure that Fred asked were the preference for the current interpretation of "Single Exit" comes from.) Also, C has had const since before many of the users here were born, so no need for capital constants anymore even in C. But Java preserved all those bad old C habits. –  sbi Nov 10 '11 at 22:08
4  
@dodgy_coder: FORTRAN had to compete with assembly language, when memory and cycles where both quite expensive. Use of ENTRY instead of splitting the function saved the memory for the additional CALL and RETURN statements, and the tens of microseconds needed to execute them. –  kevin cline Dec 2 '11 at 17:44

I say in a memory-managed language like Java, multiple exits make a lot of sense.

If you write a side-effect free methods, it is logically impossible to justify not returning as soon as you have your answer.

Let's say you have a comparator that compares on multiple criteria. The method compares on a first criteria and breaks ties on a second criteria. If there is still a tie, it compares on a third criteria.

In this case, you can return as soon as you have a non-zero comparison result or you can wrap the rest of the method in if statements. It is clear that returning as soon as you have a non-zero is most desirable. The case of comparison on first criteria, stands out and is easy to understand. The fact that looking at the second criteria is only necessary to look at in the case of a tie is also obvious.

By returning as soon as possible, you have reduced nesting and reduced the amount of code needed to understand the most basic case.

There are cases where you might not want multiple returns. For example, it can be bad to have a return that is deeply nested in a long method where it is not obvious. But long methods with deep nesting are not ideal and you can still reduce the confusion with good commenting.

So the only reason to stay in a method after you have the result is that your code has side effects. However, having side effects is not the ideal. I would personally write a side effect free method and another method that takes the result and does whatever else.

share|improve this answer

I think the best justification is, single return statements make debugging easier. I remember millions of times I had to reduce the function into single return just to print out the return value at a single point.

  int function() {
     if (bidi) { print("return 1"); return 1; }
     for (int i = 0; i < n; i++) {
       if (vidi) { print("return 2"); return 2;}
     }
     print("return 3");
     return 3;
  }
share|improve this answer
15  
I would also add that it makes debugging easier because you only ever need to set one breakpoint to catch all exits* from the function. I beleive that some IDEs let you put a breakpoint on the close brace of the function to do the same thing. (* unless you call exit) –  Skizz Nov 10 '11 at 11:03
2  
For a similar reason, it also makes it easier to extend (add to) the function, since your new functionality doesn't have to be inserted before each return. Say you needed to update a log with the result of the function call, for example. –  JeffSahol Nov 10 '11 at 16:43
23  
Honestly, if I were maintaining that code, I'd rather have a sensibly-defined _function(), with returns at appropriate places, and a wrapper named function() that handles extraneous logging, than have a single function() with contorted logic to make all returns fit into a single exit-point just so I can insert an additional statement before that point. –  ruakh Nov 13 '11 at 19:41
5  
In some debuggers (MSVS) you can put breakpoint on last closing brace –  Abyx Nov 21 '11 at 21:56

"Single Entry, Single Exit" originated with the Structured Programming revolution of the early 1970s, which was kicked off by Edsger W. Dijkstra's letter to the Editor "GOTO Statement Considered Harmful". The concepts behind structured programming were laid out in detail in the classic book "Structured Programming" by Ole Johan-Dahl, Edsger W. Dijkstra, and Charles Anthony Richard Hoare.

"GOTO Statement Considered Harmful" is required reading, even today. "Structured Programming" is dated, but still very, very rewarding, and should be at the top of any developer's "Must Read" list, far above anything from e.g. Steve McConnell. (Dahl's section lays out the basics of classes in Simula 67, which are the technical foundation for classes in C++ and all of object-oriented programming.)

share|improve this answer
7  
I bet you must be one of those guys that also litters the code with boolean flags instead of using break and continue in loops. –  hugomg Nov 9 '11 at 13:53
14  
The article was also written in the days when goto could literally go anywhere, like right into some random point in another function, bypassing any notion of procedures, functions, a call stack, etc. No sane language permits that these days with a straight goto. C's setjmp/longjmp is the only semi-exceptional case i'm aware of, and even that requires cooperation from both ends. (Semi-ironic that i used the word "exceptional" there, though, considering that exceptions do almost the same thing...) Basically, the article discourages a practice that's long dead. –  cHao Nov 9 '11 at 15:41
5  
From the last paragraph of "Goto Statement considered harmful": "in [2] Guiseppe Jacopini seems to have proved the (logical) superfluousness of the go to statement. The exercise to translate an arbitrary flow diagram more or less mechanically into a jump-less one, however, is not to be recommended. Then the resulting flow diagram cannot be expected to be more transparent than the original one." –  hugomg Nov 9 '11 at 18:22
8  
What does this have to do with the question? Yes, Dijkstra's work eventually led to SESE languages, and so what? So did Babbage's work. And perhaps you should re-read the paper if you think it says anything about having multiple exit points in a function. Because it doesn't. –  jalf Nov 9 '11 at 18:35
6  
@John, you seem to be trying to answer the question without actually answering it. It's a fine reading list, but you've neither quoted nor paraphrased anything to justify your claim that this essay and book have anything to say about the asker's concern. Indeed, outside of comments you've said nothing substantial about the question whatsoever. Consider expanding this answer. –  Shog9 Nov 9 '11 at 22:05

One of the reason for the existence of the sigle exit point guideline, in my opinion, is people tend to write long and deeply nested methods and when you have such methods, multiple returns actually reduce the code readability (which implies maintainers are more likely to introduce bugs by accident).

My high school programming teacher taught me the single exit point standard, and I had been following it religiously without really knowing why.

After I read the book Clean Code and practice the the advice of writing short and simple methods I found that multiple returns is actually not bad, especially in the case of argument validation.

I used to write code like this:

public String getSomeValue(String arg) {

  String valueToReturn = null; 

  if (arg==null) {
     valueToReturn = "";
  }  else {
     ...
     ...
     ...
     valueToReturn = "some value";
  }

  return valueToReturn;
}

And now I would write the above like:

public String getSomeValue(String arg) {

  if (arg == null) {
    return "";
  }

  ...
  ...
  ...
  valueToReturn = "some value;

  return valueToReturn;
}

What I like about the second style are:

  • The "meat" of the method is not nested inside the if block, so I get one free indentation (I try to avoid having more then 4 levels of indentation in each method).

  • The return value of corner case arguments or invalid arguments is more obvious.

I think as long as the code is not too complex, and you don't hide the returns in deeply nested blocks then multiple returns is ok. I really want to jump off a building when I see code like this:

if (somecondition) {
  if (somcecondition2) {
     if(somecondition3) {
       if(somecindition4) {
         ....
           if (somecondition10) {
               ...
               ...
               ...
               //20 lines of code after
               return "hello world";
            }
         }
      }
      ...
      ...
      ...
      return "hello monday";
   }
}
...
...
...
return "hello earth";
share|improve this answer
1  
That has nothing to do with multiple returns, and everything to do with needing to introduce a better state control. –  Lee Louviere Nov 9 '11 at 15:14

I'd say: Write methods as short as possible (I always strive for no more than 15 lines, though that maybe impossible sometimes, due to deadlines e.g.) because then it really doesn't matter which style you use. Your code will always be readable, no matter if you use single/multiple exit points, no matter if you declare variables in the smallest scope possible or at the beginning of a method (yuk, how I hate that).

share|improve this answer
7  
Someone has been reading too much Uncle Bob? :) –  Steven Jeuris Nov 9 '11 at 12:19
14  
It's impossible to read too much Uncle Bob. ;-) –  Nick Hodges Nov 9 '11 at 14:32
2  
Uncle Bob may not always be right, but he always makes sense, and always makes you think! –  Bill Michell Nov 9 '11 at 16:04
3  
Hmmm, sounds like fighting coding styles with more coding styles! –  TMN Nov 10 '11 at 15:56

It could be my lack of knowledge of Java, but are the parenthesis around the ternary operator test required? If not, don't use them.

For me (professionally anyway), I usually go with "when in Rome..." and follow the coding standard. At the end of the day, there's not much worse than inconsistencies scattered throughout a code base. If you have the luxury of a standard, I'd rather follow the standard to ensure consistency (at least on my own part) than do something that may make sense to me but confuses someone else on my team, who might make me take time out of my day to explain my changes to them.

Having said that of course, if I feel strongly about something in the standard that should be changed, then I make sure that I have concrete reasoning as to why what's currently there bothers me and exactly how my proposal makes everyone's life easier. If the lead decides that's what's best for the team and the standard and chalks up time to educate everyone on the change, cool. If not, oh well, I tried and I'll just stick to using professionally failed convention in my own code (unless my mind was changed during a discussion with a group of peers).

As far as multiple exit points go, my only gripe with them really is if they're anywhere but the beginning of a function or at the end (personally I actually only like the exit points at the end and structuring my logic to accommodate, but after having a few discussions with peers, I've found that the former doesn't make me vomit in my mouth anymore.. Well, as much as it used to anyway ;)). Finding nested return statements can be a bit of a pain and really should be avoided unless there's absolutely no option (and even then I'd suggest refactoring to fix what you have).

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.