2

When you have a function whose behaviour depends on a series of conditions, you could compute it using differents if-return blocks or with a series of if-else blocks. Example computational schemas:

void f(params) // isolated if-blocks
{
    if (cond1) {
       // computational steps
       return;
    }

    if (cond2) {
       // computational steps
       return;
    }

    // computational steps of last case
 }

 void f() // unique if-else block
 {
    if (cond1) {
       // computation
    } else if (cond2) {
       // computation
    } else { // last condition
       // computation
    }
 }

I would say the first one is always more readable, but I don't know if the second one is best from a design (maintenance/error prone) or performance (branch prediction/compiler optimizations) point of view.

What are the pros and cons of both approaches? What other things have I not considered?

ABu
  • 10,423
  • 6
  • 52
  • 103
  • 1
    I _would_ expect compiler to generate same code in both cases unless there is something really compex inside conditional operator body, but it is useless to speculate without looking at actual compiler output. – Revolver_Ocelot May 27 '16 at 23:06
  • If you're concerned about performance, you're likely compiling with -O3. In this case, I'd have to guess that they both produce the same assembly code. Don't micro-optimize for efficiency (the compiler will nearly always be better). Optimize to follow internal standards are for readability. – Donnie May 27 '16 at 23:07
  • I'd also state that the first one is slightly less readable, as unless you read every if block to check for the `return` statement, it's not obvious if the final naked block is common code or just the final case. – Donnie May 27 '16 at 23:08
  • 1
    [Consider using `switch` instead of `if`/`else if`](http://stackoverflow.com/questions/97987/advantage-of-switch-over-if-else-statement) – James Adkison May 28 '16 at 02:07

3 Answers3

6

If "computational steps" are suitably long (and sometimes this doesn't have to be long at all), then it's very hard to visually grok that there are three independent chunks, each having an early return in it. Someone might incorrectly infer that all three chunks could run in the same function call.

Version two makes it explicitly clear that only one path can be executed and I believe it's much clearer to read and maintain.

Mark B
  • 95,107
  • 10
  • 109
  • 188
  • 1
    If the "computational steps" are longer than a few lines, they should be extracted into a method anyway. But generally I agree that the 2nd version is a little bit clearer because `else` is more explicit than `return` in this context. – Frank Puffer May 28 '16 at 09:37
1

It has been observed that complex logical can get tripped up when if-then-else is used versus straightforwardly using many if-then. But the previous posts are correct, it shouldn't matter, as long as all the criteria are unique for each elseif or else statement.

There may be, however, special situations when there are numerous parameters and numerous logicals mixed together in one statement (AndAlso, OrElse, parentheses, etc) and you can't possibly enumerate all of them using elseif, else -- and you may e.g. only want to use 2 scenarios out of 20 possible combinations of parameters. Here, you assuredly would only need to use only 2 if-then statements.

0

If you put the computational steps in their own functions, your functions will look like:

void f(params) // isolated if-blocks
{
   if (cond1) {
      function_cond1();
      return;
   }

   if (cond2) {
      function_cond2();
      return;
   }

   // computational steps of last case
   function_default();
}

void f() // unique if-else block
{
   if (cond1) {
      function_cond1();
   } else if (cond2) {
      function_cond2();
   } else { // last condition
      function_default();
   }
}

When you do that, the difference between the two styles does not make a whole lot of difference. Both approaches are easy to follow.

Personally, I would prefer the first style since it allows the three blocks/conditions to be separated clearly but I don't find the second approach bad at all.

R Sahu
  • 204,454
  • 14
  • 159
  • 270