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.
It can be very useful a few times, but in general, no-fallthrough is the desired behavior. Fallthrough should be allowed, but not implicit.
An example, to update old versions of some data:
Have you heard of Duff's device? This is a great example of using switch fallthrough.
It's a feature that can be used and it can be abused, like almost all language features.
It may depend on what you consider fallthrough. I'm ok with this sort of thing:
But if you have a case label followed by code that falls through to another case label, I'd pretty much always consider that evil. Perhaps moving the common code to a function and calling from both places would be a better idea.
And please note that I use the C++ FAQ definition of "evil"
I don't like my
switch
statements to fall through - it's far too error prone and hard to read. The only exception is when multiplecase
statements all do exactly the same thing.If there is some common code that multiple branches of a switch statement want to use, I extract that into a separate common function that can be called in any branch.
Using fall-through like in your first example is clearly OK, I would not consider it a real fall-through.
The second example is dangerous and (if not commented extensively) non-obvious. I teach my students not to use such constructs UNLESS they consider it worth the to devote a comment block to it, which describes that this is an intentional fallthrough, and why this solution is better than the alternatives. This discourages sloppy use, but still makes it allowed in the cases where it is used to an advantage.
This is more or less equivalent to what we did in space projects when someone wanted to violate the coding standard: they had to apply for dispensation (and I was called on to advise about the ruling).
Powerful and dangerous. The biggest problem with fall-through is that it's not explicit. For example, if you come across frequently-edited code that has a switch with fall-throughs, how do you know that's intentional and not a bug?
Anywhere I use it, I ensure that it's properly commented: