Switch Statement Fallthrough…should it be allowed?

2019-01-04 00:08发布

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.

12条回答
戒情不戒烟
2楼-- · 2019-01-04 00:26

Fallthrough is really a handy thing, depending on what you're doing. Consider this neat and understandable way to arrange options:

switch ($someoption) {
  case 'a':
  case 'b':
  case 'c':
    // do something
    break;
  case 'd':
  case 'e':
    // do something else
    break;
}

Imagine doing this with if/else. It would be a mess.

查看更多
三岁会撩人
3楼-- · 2019-01-04 00:33

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...

switch (c) {
  case 1:
  case 2:
            ... do some of the work ...
            /* FALLTHROUGH */
  case 17:
            ... do something ...
            break;
  case 5:
  case 43:
            ... do something else ...
            break;
}

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.

查看更多
Bombasti
4楼-- · 2019-01-04 00:33

I'd love a different syntax for fallbacks in switches, something like, errr..

switch(myParam)
{
  case 0 or 1 or 2:
    // do something;
    break;
  case 3 or 4:
    // do something else;
    break;
}

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...

int value = 10;
value.Switch()
  .Case(() => { /* do something; */ }, new {0, 1, 2})
  .Case(() => { /* do something else */ } new {3, 4})
  .Default(() => { /* do the default case; */ });

Although that's probably even less readable :P

查看更多
再贱就再见
5楼-- · 2019-01-04 00:33

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.

查看更多
孤傲高冷的网名
6楼-- · 2019-01-04 00:34

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:

  • it's easy to "forget" a break
  • it's not always obvious for code maintainers THAT an omitted break was intentional

good use of a switch/case fallthrough:

switch (x)
{
case 1:
case 2:
case 3:
 do something
 break;
}

BAAAAAD use of a switch/case fallthrough:

switch (x)
{
case 1:
    some code
case 2:
    some more code
case 3:
    even more code
    break;
}

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.

查看更多
不美不萌又怎样
7楼-- · 2019-01-04 00:38

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".

查看更多
登录 后发表回答