« NetBeans plugins I... | Main | See you soon? »

20050613 Monday June 13, 2005

OnlyOneReturn Considered Harmful

The other day I mentioned PMD and how it's vital to learn how to customize the ruleset, since by default it includes some rules that are evil. Evil I tell you!

My favorite rule to hate is the OnlyOneReturn rule. This rule basically says that

A method should have only one exit point, and that should be the last statement in the method.
Unfortunately, the rule author does not provide supporting documentation for this point of view, and I personally cannot think of any. In fact, restricting yourself to a single return statement makes the code less readable. Take the following method from the JDK's Integer class for example.

    public static String toString(int i) {
        if (i == Integer.MIN_VALUE) {
            return "-2147483648";
        }

        int size = (i < 0) ? (stringSize(-i) + 1) : stringSize(i);
        char[] buf = new char[size];
        getChars(i, size, buf);

        return new String(0, size, buf);
    }
We have a special case, and it's dealt with right at the beginning of the method. If we hadn't done that, we would need to slap a big else block around the remainder of the code, as well as introduce a temporary variable, e.g. result, to hold the return value that we then return as the last statement of the method.

The above is a trivial example, but I frequently write code where I have multiple exit points early in the method that deal with special cases, and this avoids the need for deeply nested code.

Creator's Visual Page Designer Source Code: Proud OnlyOneReturn Rule Violator Since 2003.

(2005-06-13 10:52:23.0) Permalink Comments [9]

Comments:

Amen to that, it was the first rule I blitzed as well. However the standard PMD ruleset has a few other problems as well as that one - see http://bleaklow.com/blog/archive/000157.html

Posted by Alan Burlison on June 13, 2005 at 01:52 PM PDT #

I'm in total agreement as well. Given a choice between increasing the method complexity by adding nested brackets and using more <tt>return</tt>s, I always favour more <tt>return</tt> statements. <p/>I still try to avoid deeply nested <tt>return</tt>s as I find they aren't always obvious when scanning a method. I prefer that <tt>return</tt>s are obvious. <p/>In C code I've been using a style which I've recently learned is fairly common. The style involves having a single function return and acommon error handling block at the end of the function. Function then get written in the form :
int func(int param) {
  int result;

  if( precondition ) {
    return somesimpleresult;
  }

  /* mainbody */

  goto CommonExit;

  ErrorExit:

  /* Do error cleanup */

  Commonexit:
  /* common cleanup */
  
  return result;
}
<tt>goto</tt>s are only ever forward branching and towards the eventual <tt>return</tt>. In Java code <tt>finally</tt> clauses are roughly equivalent.

Posted by Mike Duigou on June 13, 2005 at 08:30 PM PDT #

I agree that you the "only one return" rule may increase the complexity of the source code, and I can't think of a single case it might increase the readability. I do however _really_ dislike the goto statement...

Posted by Trond Norbye on June 14, 2005 at 05:56 AM PDT #

It's funny seeing "goto" being brought up here, since I chose a title for this blog entry, "OnlyOneReturn considered harmful", as a play on the title of the classic anti-goto article by Dijkstra: "Go To Statement Considered Harmful". http://www.acm.org/classics/oct95/

Posted by Tor Norbye on June 14, 2005 at 06:07 AM PDT #

The usual case for a single exit point is when you have to perform a certain common task before you leave the method. <p /> If you wrote a method using multiple exit points and you later detect that you need some kind of cleanup on exiting you will have to restructure your code quite a bit. <p /> Another advantage of consistently using a structure like
{
  T result = <defaultValue>;
  ...
  return result;
}
is that you can watch the result variable in the debugger. Not sure whether you can watch the method's return value. <p/> There may be other reasons that are more important to C than to Java developers. At least I have met a lot of these girls and guys that passionately hated code that uses multiple exit points. <p /> For method bodies that are 10 lines or fewer (like your sample) it is hard to see why one style should be easier to comprehend than the other.

Posted by George on June 23, 2005 at 04:40 AM PDT #

I use the "finally" structure in Java for that (ensuring that code is run before the method is exited).

Posted by Tor Norbye on June 23, 2005 at 06:21 AM PDT #

Yup, I like doing early exits too... so I put that one in the "controversial" ruleset. Some folks do like it, though, so we keep it around.

Posted by Tom Copeland on July 10, 2005 at 12:10 AM PDT #

Yeah, I think this is mostly a task for the NetBeans plugin developers now, since in the current plugin version, that's where the list of rules to run (which includes OnlyOneReturn) are taken from. I'm glad to hear it's in the controversial set :) Sorry if I got a little out of hand here - I guess I take coding style very seriously. But that's also why I love PMD!

Posted by 192.18.98.64 on July 10, 2005 at 12:59 AM PDT #

Sure, yup, no problem, I definitely agree with you... I certainly don't like all the rules. Actually, I never run all the rules; I just run basic, unusedcode, and pick out a couple from design and whatnot.

Posted by Tom Copeland on July 10, 2005 at 10:30 AM PDT #

Post a Comment:

Comments are closed for this entry.