With return
statements in each if
branch.
In your code, you have return
statements in each of the if conditions. When you have a situation like this, there are two ways to write this. The first is how you've written it in Example 1:
if (a == b1) {
return c1;
} else if (a == b2) {
return c2;
} else {
return c11;
}
The other is as follows:
if (a == b1) {
return c1;
}
if (a == b2) {
return c2;
}
return c11; // no if or else around this return statement
These two ways of writing your code are identical.
The way you wrote your code in example 2 wouldn't compile in C++ or Java (and would be undefined behavior in C), because the compiler doesn't know that you've covered all possible values of a
so it thinks there's a code path through the function that can get you to the end of the function without returning a return value.
if (a == b1) {
return c1;
}
if (a == b2) {
return c2;
}
...
if (a == b11) {
return c11;
}
// what if you set a to some value c12?
Without return
statements in each if
branch.
Without return
statements in each if
branch, your code would be functionally identical only if the following statements are true:
- You don't mutate the value of
a
in any of the if
branches.
==
is an equivalence relation (in the mathematical sense) and none of the b1
thru b11
are in the same equivalence class.
==
doesn't have any side effects.
To clarify further about point #2 (and also point #3):
==
is always an equivalence relation in C or Java and never has side effects.
- In languages that let you override the
==
operator, such as C++, Ruby, or Scala, the overridden ==
operator may not be an equivalence relation, and it may have side effects. We certainly hope that whoever overrides the ==
operator was sane enough to write an equivalence relation that doesn't have side effects, but there's no guarantee.
- In JavaScript and certain other programming languages with loose type conversion rules, there are cases built into the language where
==
is not transitive, or not symmetric. (In Javascript, ===
is an equivalence relation.)
In terms of performance, example #1 is guaranteed not to perform any comparisons after the one that matches. It may be possible for the compiler to optimize #2 to skip the extra comparisons, but it's unlikely. In the following example, it probably can't, and if the strings are long, the extra comparisons aren't cheap.
if (strcmp(str, "b1") == 0) {
...
}
if (strcmp(str, "b2") == 0) {
...
}
if (strcmp(str, "b3") == 0) {
...
}