Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

When is it appropriate to use a fall-through (classic) switch statement? Is such usage recommended and encouraged or should it be avoided at all costs?

share|improve this question
    
Not all languages allow fall-through on switch statements. –  Oded Oct 25 '11 at 19:17
    
@Oded, edited, added "classic" word. Not all languages allow fall through, nevertheless I insist it is classic ) –  shabunc Oct 25 '11 at 19:22
3  
If you are talking about Duffs' device, that's one thing. –  Oded Oct 25 '11 at 19:23
3  
@Oded: That's the first thing most people think of, but that's hardly "appropriate." According to this, Duff himself said "This definitely provides an argument in the discussion whether switch should fall through by default, but I'm not sure if the argument is for or against it." –  BlueRaja - Danny Pflughoeft Oct 26 '11 at 5:32
add comment

6 Answers

up vote 9 down vote accepted

Here's an example where it would be useful.

public Collection<LogItems> GetAllLogItems(Level level) {
    Collection<LogItems> result = new Collection<LogItems>();
    switch (level) {
        // Note: fall through here is INTENTIONAL
        case All:
        case Info:
             result.Add(GetItemsForLevel(Info));
        case Warning:
             result.Add(GetItemsForLevel(Warning));
        case Error:
             result.Add(GetItemsForLevel(Error));
        case Critical:
             result.Add(GetItemsForLevel(Critical));
        case None:
    }
    return result;
}

This sort of thing (where one case includes the other) is rather rare, I think, which is why some newer languages either don't allow fallover or require special syntax for it.

share|improve this answer
7  
This example, while interesting, is lacking the requisite all-caps // INTENTIONAL FALL THROUGH HERE comment. –  Russell Borogove Oct 26 '11 at 1:45
    
It's just as easy to write this code with falling through by having the GetItemsForLevel(Info) call invoke GetItemsForLevel(Warning) and so on. –  Caleb Oct 26 '11 at 14:55
    
@RussellBorogove: Absolutely correct. –  configurator Oct 26 '11 at 15:15
    
@Caleb: In this case, yes. But what if the calls were a little more complicated? It could get a bit hairy, while fall through makes it seem simple. I should note I'm not actually in favour of using fall through - I'm just saying it can be useful in certain situations. –  configurator Oct 26 '11 at 15:17
add comment

I use them when certain functionality has to be applied for more than one value. For example, say you had an object with a property called operationCode. If the code equals 1, 2, 3 or 4, you want to startOperationX(). If it's 5 or 6, you want to startOperationY() and 7 you startOperationZ(). Why have 7 complete cases with functionality and breaks when you can use fall-throughs?

I think it's completely valid in certain situations, especially if it avoids 100 if-else statements. =)

share|improve this answer
4  
What you're describing is a switch with multiple cases tied to the same code. That's different than a fall-through, where execution of one case continues into the next one because of the lack of a break between them. –  Blrfl Oct 25 '11 at 20:47
2  
It doesn't really matter, the fall-through is just the lack of a break statement so it "falls through" to the next case. –  Yatrix Oct 25 '11 at 21:02
    
I'd re-word the scenario in your answer to reflect that. –  Blrfl Oct 25 '11 at 21:11
2  
@Yatrix: I disagree. It is much different to have consecutive cases all executing the exact same block of code than it is to omit a break. One is routine, the other far from it (ime) - and the potential for misreading and unintended control flow is much greater. –  qes Oct 25 '11 at 23:33
    
@qes yes, it's different, but they are both fall-throughs. He asked when/if it'd be appropriate. I gave an example of when it would. It wasn't meant to be an all-inclusive example. Depending on the language, having statements before a fall-through may not work. I don't think it will with C# stackoverflow.com/questions/174155/… –  Yatrix Oct 26 '11 at 13:15
show 2 more comments

I've used them occasionally, I think its always appropriate usage - but only when included with the appropriate comment.

share|improve this answer
    
+1 for requiring a comment. –  Caleb Oct 25 '11 at 20:33
add comment

It depends on:

  • your personal preference
  • your employer's coding standards
  • the amount of risk involved

The two main problems associated with letting one case fall through to the next are:

  1. It makes your code dependent on the order of the case statements. That's not the case if you never fall through, and it adds a degree of complexity that's often unwelcome.

  2. It's not obvious that the code for one case includes the code for one or more subsequent cases.

Some places explicitly prohibit falling through. If you don't work at such a place, and if you're comfortable with the practice, and if breaking the code in question won't cause any real suffering, then it might not be the worst thing in the world. If you do it, though, be sure to put an attention-grabbing comment nearby to warn those who come later (including the future you).

share|improve this answer
add comment

If I feel a need to go from one case to another (rare, admittedly), I prefer to be very explicit and goto case, of course, that assumes your language supports it.

Because falling thru is so uncommon, and very easy to overlook while reading code, I feel it is appropriate to be explicit - and a goto, even if it's to a case, should stand out like a sore thumb.

It also helps avoid bugs that may occur when case statements are reordered.

share|improve this answer
add comment

Fall-through cases are perfectly fine. I often find that an enumeration is used in lots of places, and that when you don't need to differentiate some cases it is easier to use fall-through logic.

For example (note the explanatory comments):

public boolean isAvailable(Server server, HealthStatus health) {
  switch(health) {
    // Equivalent positive cases
    case HEALTHY:
    case UNDER_LOAD:
      return true;

    // Equivalent negative cases
    case FAULT_REPORTED:
    case UNKNOWN:
    case CANNOT_COMMUNICATE:
      return false;

    // Unknown enumeration!
    default:
      LOG.warn("Unknown enumeration " + health);
      return false;
  }
}

I find this kind of use perfectly acceptable.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.