Interestingly, this optimization is relatively new for LLVM:
http://llvm.1065342.n5.nabble.com/llvm-dev-RFC-JumpMaps-swit...
Yes, this is exactly one of the reasons to use switch statements instead of if-elseif-else, were possible.
Even if in the absence of side effects it is still easy to have overlapping conditions in the if-elseif-else, for example misspelling an enumeration value, some copy/paste mistake, etc. A switch statement does not allow this.
>> If you're checking some status code, I still prefer ifs
My philosophy is always to write code that expresses as much as possible its intent, and the sequence of operations the computer has to take. Performing some action based on a status code, in my mind, is like looking a procedure by its label, and executing it. Not looking at all procedures one-by-one until you find one that 'advertises' it applies to your status code. To each their own, I guess ;-)
if (x) {
else if (x) {
// warning
}
>> My philosophy is always to write code that expresses as much as possible its intent
agreed>>, and the sequence of operations the computer has to take. From a performance perspective yes, from a logic / maintanance perspective not really.
Interestingly, neither clang nor g++ give a warning for this case:
int main(int argc, char **argv)
{
int x = argc;
if (x == 0)
{
x = 10;
}
else if (x == 1)
{
x = 20;
}
else if (x == 0)
{
x = 30;
}
return 0;
}
# g++ bla.cpp -o out -Wall
(no warning) # clang bla.cpp -o out -Wall
(no warning)I assume this is because the compiler can never be 100% sure a variable cannot be changed midway through testing each of the conditions because of aliasing, so it won't throw a warning. In this particular example this obviously is not relevant, but I can imagine some pathological example where one of the tests has side effects that change the result of the later tests, and to avoid false positives the compiler simply never warns about unreachable code for these things.
In a sense, this is exactly what I mean by writing code that matches exactly what you want to happen. If I write 'switch (x)', it's pretty clear the test is executed exactly once. If I write a sequence of if-elseif-elseif-else statements, the conditions are evaluated in sequence, which is not what I want.
This is all reasoning from the perspective of a compiled language of course. But even in Javascript implementing switch-statements as if-elseif-else seems like an anti-pattern to me.
>> Switch statements are a more like goto, and are more low level.
I know about 'goto considered harmful', but sometimes a simple jump table is just what you need, no need to come up with 'better' ways ;-)