views:

679

answers:

10

Possible Duplicate:
Should a function have only one return statement?

Hi,

I have a code somethg like below:

    int method(string a ,int b , int c){
    if(cond1)
    return -1;

    if(cond2 || cond3)
    return 3;

    if(cond1 && cond2)
    return 0;
else
return -999;
    }

Does it perform badly when compared to having multiple if else and have single return?

EDIT:

Thank you for all your answers.

+7  A: 

Performance difference will be negligible - some people may not prefer the style of this code but there will be little to no performance difference. If anything your code will be slightly faster for many cases.

Andrew Hare
More important than speed is how there would be less nesting. I don't know about you, but more than a couple levels deep starts to get confusing for me..
Brendan Long
+21  A: 

It's perfectly OK. It also usually leads to clearer code - no deep nesting of "if"s

ob1
And avoids introduction of flag variables to track branches that would otherwise be a return.
Richard
As a final note, you do not require the else before the last return. It is a given that if you have reached the end of hte method then none of the ifs have matched and you are in an else statement. Consider it the `default:` of a switch.
Matt S
+1  A: 

Perform badly? No. Some people think it's less readable, but that's a religious argument.

Paul Tomblin
+3  A: 

Does it perform badly when compared to having multiple if else and have single return?

It probably makes no difference. And if there is a difference it will probably be insignificant.

Stop wasting your time trying to micro-optimizing your code. Concentrate on trying to get your code to work, and making it easy for the next guy to read / maintain.

Stephen C
+1  A: 

Performance difference is negligible, but multiple exit points from a function can lead to a source code difficult to mantain: if the function is non trivial it will be easy to overlook an exit point when analyzing the code searching for some problem, especially if some time passed.

garph0
Conversely, trying to force a single exit point can *also* make the code difficult to analyze. This is particularly the case when you've got quite a few set-up steps (where early exit would help reduce the nesting level) or when you've got some nested loops and a code style that prohibits `break` and `continue` (where you've got to introduce complex state variables to compensate).
Donal Fellows
A: 

Returning in multiple places like that is called an "early return". People use early returns sometimes to make their code run better:

e.g.

void doit( int param )
{
  // param must be +!  else no point in
  // continuing w function
  if( param < 0 )
  {
    return ;
  }

  // ... rest of code ...
  // main code returns
  return ;
}

compare with

void doit( int param )
{
  // param must be +!  else no point in
  // continuing w function
  if( param > 0 )
  {
     // .. actual code ..
  }
  else
  {
     puts( "Sorry, param must be > 0!" ) ;
  }

  // one return for all here
  return ;
}

SO, just look at the two styles and make a choice. Early returns are used in performance critical code (like intersections) because you want the function to complete as fast as possible (same code runs thousands of times per second, so every compare counts)

On the other hand "early return" code can be difficult to debug, because you might be like "Well that function doesn't even seem to run.. OH! the early return."

bobobobo
+8  A: 

It increases the cyclomatic complexity (CI) of a function - i.e., increases the number of paths thru code more than does using the same number of if statements.

Is this bad? Yes, if your shop runs static code analysis software. And your boss sees that you bumped CI by 3. :)

http://en.wikipedia.org/wiki/Cyclomatic_complexity

No negative performance effect, though.

jim mcnamara
If you have a boss who pays attention to cyclomatic complexity, you need a new boss. Cyclomatic complexity is pseudo-science ... as illustrated by this example.
Stephen C
Multiple returns in a function is more complex than just one return statement... But far simpler than deeply nested conditionals.
Arafangion
@Stephen - I was not defending using graph theory to map code paths - which does have some merit - the OP wanted to know about a downside. I think. So, giving managers a tool that spouts simple numbers and purports to show code quality via numbers is a downside. As you demonstrate.
jim mcnamara
@jim - it is a downside of giving credence to cyclomatic complexity, not of using multiple returns. Suppose, for example, you had a boss who had the insane idea that exceptions should always be caught immediately. Would you consider this to be a downside for the (correct) use of exceptions?
Stephen C
@Stephen your analogy is correct, your assertion is wrong. Do you have references WRT: The theorems used in McCabe's paper are false?Do you have references at all? Assertions are fine with me, just back them up. Fair enough? BTW: a reference is a citation of a paper from a refereed journals or maybe archiv.org. A reference is not a link to somebody's blog wherein it does not cite real references.
jim mcnamara
+1  A: 

Putting aside the fact that your final "else" statement is redundant, there's nothing intrinsically wrong with your sample. It starts to become less than ideal from a debugging perspective when you want to trap the method's return value, because you may be left having to place breakpoints on each of the return statements. Multiple exit points aren't great, generally speaking. While your sample is manageable, it's not a stretch to imagine the need for a longer series of tests, in which case debugging becomes a chore. So assign the return value to a variable and return the variable at the end of the method.

One final point: use "switch" statements if you can (or place the most likely "success" tests towards the beginning of your list). Switch statements are quicker.

In the long term you may also find it helpful to use curly braces regardless. For example:

if (cond1) {
    return -1;
}

IMHO it's an investment as I believe it leads to fewer mistakes.

Chris
A: 

It can be used easily in small functions as in your example. Also, as bobobobo said, using it in "early return" is nice thing.

But It usually make big functions harder to maintain (in C at least). Imagine if you have a function with opened resources (file handler, database connection, ...) and you want to return. It will be cumbersome to close resources on each return!

Another approach we used:

int my_func(int foo)
{
   int x,y,z;
   FILE* file;
   // do some stuff
   if(x>5)
     goto my_func_end;

   // do some other stuff.

   my_func_end:
      if(file != NULL)
         fclose(file);
      return y;
}

It is better to have local-variables cleaning in one location. Also note that single return statements is advised by some coding standards, like MISRA.

There is an interesting question similar to this on here.

If you have time, take a look here and here.

Yousf
If things are particularly complex, you can split into two functions. One checks preconditions, allocates and cleans up resources, and passes (known correct) things into the other, which does the actual work. Of course, that's also often the point where you split code if you're inserting an SPI…
Donal Fellows
+6  A: 

[Code sample not quoted]

You should quit worrying about micro-optimizations and start worrying about indenting code in a way that people can read it.

Does it perform badly when compared to having multiple if else and have single return?

Any reasonable compiler (i.e., anything beyond a simple interpreter or really stupid JIT) will convert your program to a control-flow graph where it does not matter how the control flow is written in the source code. For the compiler cares, you could be using goto.

Stop worrying about the wrong things!

Norman Ramsey