For as long as I can remember I have avoided using switch statement fallthrough. Actually, I can't remember it ever entering my consciousness as a possible way to do things as it was drilled into my head early on that it was nothing more than a bug in the switch statement. However, today I ran across some code that uses it by design, which got me immediately wondering what everyone in the community thinks about switch statement fallthrough.
Is it something that a programming language should explicitly not allow (like C# does, though it supplies a workaround) or is it a feature of any language that is powerful enough to leave in the programmer's hands?
Edit: I wasn't specific enough to what I meant by fallthrough. I use this type a lot:
switch(m_loadAnimSubCt){
case 0:
case 1:
// Do something
break;
case 2:
case 3:
case 4:
// Do something
break;
}
However, I'm concerned about something like this.
switch(m_loadAnimSubCt){
case 0:
case 1:
// Do something but fall through to the other cases
// after doing it.
case 2:
case 3:
case 4:
// Do something else.
break;
}
This way whenever the case is 0, 1 it will do everything in the switch statement. I've seen this by design and I just don't know if I agree that switch statements should be used this way. I think the first code example is a very useful and safe. The second seems kind of dangerous.
Fallthrough is really a handy thing, depending on what you're doing. Consider this neat and understandable way to arrange options:
Imagine doing this with if/else. It would be a mess.
It's a two-edged sword. Sometimes very useful, often dangerous.
When is it good? When you want 10 cases all processed the same way...
The one rule I like is that if you ever do anything fancy where you exclude the break, you need a clear comment /* FALLTHROUGH */ to indicate that was your intention.
I'd love a different syntax for fallbacks in switches, something like, errr..
Note: This would already be possible with enums, if you declare all cases on your enum using flags right? Doesn't sound so bad either, the cases could (should?) very well be part of your enum already.
Maybe this would be a nice case (no pun intended) for a fluent interface using extension methods? Something like, errr...
Although that's probably even less readable :P
In some instances, using fall-throughs is an act of laziness on the part of the programmer - they could use a series of || statements, for example, but instead use a series of 'catch-all' switch cases.
That being said, I've found them to be especially helpful when I know that eventually I'm going to need the options anyway (for example in a menu response), but have not yet implemented all the choices. Likewise, if you're doing a fall-through for both 'a' and 'A', I find it substantially cleaner to use the switch fall-through than a compound if statement.
It's probably a matter of style and how the programmers think, but I'm not generally fond of removing components of a language in the name of 'safety' - which is why I tend towards C and its variants/descendants more than, say, Java. I like being able to monkey-around with pointers and the like, even when I have no "reason" to.
As with anything: if used with care, it can be an elegant tool.
However, i think the drawbacks more than justify NOT to use it, and finally not to allow it anymore (C#). Among the problems are:
good use of a switch/case fallthrough:
BAAAAAD use of a switch/case fallthrough:
This can be rewritten using if/else constructs with no loss at all in my opinion.
My final word: stay away from fall-through case labels as in the BAD example, unless you are maintaining legacy code where this style is used and well understood.
fall thought should be used only when it is used as a jump table into a block of code. If there is any part of the code with an unconditional break before more cases, all the case groups should end that way. Anything else is "evil".