Why Switch/Case and not If/Else If?

C++CSwitch StatementConditional Statements

C++ Problem Overview


This question in mainly pointed at C/C++, but I guess other languages are relevant as well.

I can't understand why is switch/case still being used instead of if/else if. It seems to me much like using goto's, and results in the same sort of messy code, while the same results could be acheived with if/else if's in a much more organized manner.

Still, I see these blocks around quite often. A common place to find them is near a message-loop (WndProc...), whereas these are among the places when they raise the heaviest havoc: variables are shared along the entire block, even when not propriate (and can't be initialized inside it). Extra attention has to be put on not dropping break's, and so on...

Personally, I avoid using them, and I wonder wether I'm missing something?

Are they more efficient than if/else's? Are they carried on by tradition?

C++ Solutions


Solution 1 - C++

Summarising my initial post and comments - there are several advantages of switch statement over if/else statement:

  1. Cleaner code. Code with multiple chained if/else if ... looks messy and is difficult to maintain - switch gives cleaner structure.

  2. Performance. For dense case values compiler generates jump table, for sparse - binary search or series of if/else, so in worst case switch is as fast as if/else, but typically faster. Although some compilers can similarly optimise if/else.

  3. Test order doesn't matter. To speed up series of if/else tests one needs to put more likely cases first. With switch/case programmer doesn't need to think about this.

  4. Default can be anywhere. With if/else default case must be at the very end - after last else. In switch - default can be anywhere, wherever programmer finds it more appropriate.

  5. Common code. If you need to execute common code for several cases, you may omit break and the execution will "fall through" - something you cannot achieve with if/else. (There is a good practice to place a special comment /* FALLTHROUGH */ for such cases - lint recognises it and doesn't complain, without this comment it does complain as it is common error to forgot break).

Thanks to all commenters.

Solution 2 - C++

Well, one reason is clarity....

if you have a switch/case, then the expression can't change.... i.e.

switch (foo[bar][baz]) {
case 'a':
    ...
    break;
case 'b': 
    ...
    break;
}

whereas with if/else, if you write by mistake (or intent):

if (foo[bar][baz] == 'a') {
    ....
}
else if (foo[bar][baz+1] == 'b') {
    ....
}

people reading your code will wonder "were the foo expressions supposed to be the same", or "why are they different"?

Solution 3 - C++

please remember that case/select provides additional flexibility:

  • condition is evaluated once
  • is flexible enough to build things like the Duff's device
  • fallthrough (aka case without break)

as well as it executes much faster (via jump/lookup table) * historically

Solution 4 - C++

Also remember that switch statements allows the flow of control to continue, which allows you to nicely combine conditions while allowing you to add additional code for certain conditions, such as in the following piece of code:

switch (dayOfWeek)
{
    case MONDAY:
        garfieldUnhappy = true;
    case TUESDAY:
    case WEDNESDAY:
    case THURSDAY:
    case FRIDAY:
       weekDay = true;
       break;
    case SATURDAY:
       weekendJustStarted = true;
    case SUNDAY:
       weekendDay = true;
       break;
}

Using if/else statements here instead would not be anywhere as nice.

if (dayOfWeek == MONDAY)
{
    garfieldUnhappy = true;
}
if (dayOfWeek == SATURDAY)
{
    weekendJustStarted = true;
}
if (dayOfWeek == MONDAY || dayOfWeek == TUESDAY || dayOfWeek == WEDNESDAY
    || dayOfWeek == THURSDAY || dayOfWeek == FRIDAY)
{
    weekDay = true;
}
else if (dayOfWeek == SATURDAY || dayOfWeek == SUNDAY)
{
    weekendDay = true;
}

Solution 5 - C++

If there are lots of cases, the switch statement seems cleaner.

It's also nice when you have multiple values for which you want the same behavior - just using multiple "case" statements that fall through to a single implementation is much easier to read than a if( this || that || someotherthing || ... )

Solution 6 - C++

It might also depend on your language -- For example, some languages switch only works with numeric types, so it saves you some typing when you're working with an enumerated value, numeric constants... etc...

If (day == DAYOFWEEK_MONDAY) {
    //...
}
else if (day == DAYOFWEEK_TUESDAY) {
    //...
}
//etc...

Or slightly easier to read...

switch (day) {
    case DAYOFWEEK_MONDAY :
        //...
    case DAYOFWEEK_TUESDAY :
        //...
    //etc...
}

Solution 7 - C++

Switch/case is usually optimized more efficiently than if/else if/else, but is occasionally (depending on language and compiler) translated to simple if/else if/else statements.

I personally think switch statements makes code more readable than a bunch of if statements; provided that you follow a few simple rules. Rules you should probably follow even for your if/else if/else situations, but that's again my opinion.

Those rules:

  • Never, ever, have more than one line on your switch block. Call a method or function and do your work there.
  • Always check for break/ case fallthrough.
  • Bubble up exceptions.

Solution 8 - C++

Clarity. As I said here, a clue that else if is problematic is

> the frequency with which ELSE IF is > used in a far more constrained way > than is allowed by the syntax. It is a > sledgehammer of flexibility, > permitting entirely unrelated > conditions to be tested. But it is > routinely used to swat the flies of > CASE, comparing the same expression > with alternate values... > > This reduces the readability of the > code. Since the structure permits a > universe of conditional complexity, > the reader needs to keep more > possibilities in mind when parsing > ELSE IF than when parsing CASE.

Solution 9 - C++

Actually a switch statement implies that you are working off of something that is more or less an enum which gives you an instant clue what's going on.

That said, a switch on an enum in any OO language could probably be coded better--and a series of if/else's on the same "enum" style value would be at least as bad and even worse at conveying meaning.

Solution 10 - C++

addressing the concern that everything inside the switch has equivalent scope, you can always throw your case logic into another { } block, like so ..

switch( thing ) {
    case ONETHING: {
        int x; // local to the case!
        ...
        }
        break;
    case ANOTHERTHING: {
        int x; // a different x than the other one
        }
        break;
}

.. now I'm not saying that's pretty. Just putting it out there as something that's possible if you absolutely have to isolate something in one case from another.

one other thought on the scope issue - it seems like a good practice to only put one switch inside a function, and not a lot else. Under those circumstances, variable scope isn't as much of a concern, since that way you're generally only dealing with one case of execution on any given invocation of the function.

ok, one last thought on switches: if a function contains more than a couple of switches, it's probably time to refactor your code. If a function contains nested switches, it's probably a clue to rethink your design a bit =)

Solution 11 - C++

switch case is mainly used to have the choice to made in the programming .This is not related the conditional statement as :

if your program only require the choice to make then why you use the if/else block and increase the programming effort plus it reduce the execution speed of the program .

Solution 12 - C++

Pretty sure they compile to the same things as if/else if, but I find the switch/case easier to read when there are more than 2 or 3 elses.

Solution 13 - C++

Switch statements can be optimized for speed, but can take up more memory if the case values are spread out over large numbers of values.

if/else are generally slow, as each value needs to be checked.

Solution 14 - C++

A Smalltalker might reject both switch and if-then-else's and might write something like:-

shortToLongDaysMap := Dictionary new.

shortToLongDaysMap
at: 'Mon'     put:  'Monday';
at: 'Tue'     put:  'Tuesday';
at: 'Wed'     put:  'Wednesday'
etc etc.

longForm := shortToLongDaysMap at: shortForm ifAbsent: [shortForm]

This is a trivial example but I hope you can see how this technique scales for large numbers of cases.

Note the second argument to at:IfAbsent: is similar to the default clause of a case statement.

Solution 15 - C++

The main reason behind this is Maintainability and readability. Its easy to make code more readable and maintainable with Switch/case statement then if/else. Because you have many if/else then code become so much messy like nest and its very hard to maintain it.

And some how execution time is another reason.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionOB OBView Question on Stackoverflow
Solution 1 - C++qrdlView Answer on Stackoverflow
Solution 2 - C++Eric H.View Answer on Stackoverflow
Solution 3 - C++dfaView Answer on Stackoverflow
Solution 4 - C++Joseph PatersonView Answer on Stackoverflow
Solution 5 - C++Eric PetroeljeView Answer on Stackoverflow
Solution 6 - C++hugowareView Answer on Stackoverflow
Solution 7 - C++RandolphoView Answer on Stackoverflow
Solution 8 - C++Carl ManasterView Answer on Stackoverflow
Solution 9 - C++Bill KView Answer on Stackoverflow
Solution 10 - C++JustJeffView Answer on Stackoverflow
Solution 11 - C++sandy101View Answer on Stackoverflow
Solution 12 - C++BillView Answer on Stackoverflow
Solution 13 - C++ErixView Answer on Stackoverflow
Solution 14 - C++KHWPView Answer on Stackoverflow
Solution 15 - C++AzharView Answer on Stackoverflow