Should switch statements always contain a default

2019-01-04 06:00发布

In one of my first code reviews (a while back), I was told that it's good practice to include a default clause in all switch statements. I recently remembered this advice but can't remember what the justification was. It sounds fairly odd to me now.

  1. Is there a sensible reason for always including a default statement?

  2. Is this language dependent? I don't remember what language I was using at the time - maybe this applies to some languages and not to others?

19条回答
祖国的老花朵
2楼-- · 2019-01-04 06:33

Should a "switch" statement always include a default clause? No. It should usually include a default.

Including a default clause only makes sense if there's something for it to do, such as assert an error condition or provide a default behavior. Including one "just because" is cargo-cult programming and provides no value. It's the "switch" equivalent of saying that all "if" statements should include an "else".

Here's a trivial example of where it makes no sense:

void PrintSign(int i)
{
    switch (Math.Sign(i))
    {
    case 1:
        Console.Write("positive ");
        break;
    case -1:
        Console.Write("negative ");
        break;
    default: // useless
    }
    Console.Write("integer");
}

This is the equivalent of:

void PrintSign(int i)
{
    int sgn = Math.Sign(i);
    if (sgn == 1)
        Console.Write("positive ");
    else if (sgn == -1)
        Console.Write("negative ");
    else // also useless
    {
    }
    Console.Write("integer");
}
查看更多
劫难
3楼-- · 2019-01-04 06:33

As far as i see it the answer is 'default' is optional, saying a switch must always contain a default is like saying every 'if-elseif' must contain a 'else'. If there is a logic to be done by default, then the 'default' statement should be there, but otherwise the code could continue executing without doing anything.

查看更多
Ridiculous、
4楼-- · 2019-01-04 06:38

If there is no default case in a switch statement, the behavior can be unpredictable if that case arises at some point of time, which was not predictable at development stage. It is a good practice to include a default case.

switch ( x ){
  case 0 : { - - - -}
  case 1 : { - - - -}
}

/* What happens if case 2 arises and there is a pointer
* initialization to be made in the cases . In such a case ,
* we can end up with a NULL dereference */

Such a practice can result in a bug like NULL dereference, memory leak as well as other types of serious bugs.

For example we assume that each condition initializes a pointer. But if default case is supposed to arise and if we don’t initialize in this case, then there is every possibility of landing up with a null pointer exception. Hence it is suggested to use a default case statement, even though it may be trivial.

查看更多
手持菜刀,她持情操
5楼-- · 2019-01-04 06:39

Atleast it is not mandatory in Java. According to JLS, it says atmost one default case can be present. Which means no default case is acceptable . It at times also depends on the context that you are using the switch statement. For example in Java, the following switch block does not require default case

private static void switch1(String name) {
    switch (name) {
    case "Monday":
        System.out.println("Monday");
        break;
    case "Tuesday":
        System.out.println("Tuesday");
        break;
    }
}

But in the following method which expects to return a String, default case comes handy to avoid compilation errors

    private static String switch2(String name) {
    switch (name) {
    case "Monday":
        System.out.println("Monday");
        return name;

    case "Tuesday":
        System.out.println("Tuesday");
        return name;

    default:
        return name;
    }
}

though you can avoid compilation error for the above method without having default case by just having a return statement at the end, but providing default case makes it more readable.

查看更多
狗以群分
6楼-- · 2019-01-04 06:39

Because MISRA C says so:

The requirement for a final default clause is defensive programming. This clause shall either take appropriate action or contain a suitable comment as to why no action is taken.

That said, I recommend against following MISRA C on this, for most software:

  • This defensive programming style guide doesn't care that only some values may be valid – if the variable is physically capable of taking on a value, even if that would be a bug, you're supposed to handle it. Most software should prefer to print a stack trace instead of "handling" bugs (as mentioned by Ophir Yoktan).
  • Enum switches, in particular, should have no default clause (as Harlan Kassler said). And, as Harlan also eminently demonstrates, handling invalid values can be done outside the switch – a point that was missing in Misra's discussion.
查看更多
啃猪蹄的小仙女
7楼-- · 2019-01-04 06:40

No.

What if there is no default action, context matters. What if you only care to act on a few values?

Take the example of reading keypresses for a game

switch(a)
{
   case 'w':
     // Move Up
     break;
   case 's':
     // Move Down
     break;
   case 'a':
     // Move Left
     break;
   case 'd':
     // Move Right
     break;
}

Adding:

default: // Do nothing

Is just a waste of time and increases the complexity of the code for no reason.

查看更多
登录 后发表回答