1

With the following code:

case "GETSITES":
case "SITESETUP":
    MessageBox.Show("Help! I am suffering from the Air-Conditioned Nightmare!!!");
    // ...

Will the MessageBox.Show be executed either the switch value is "GETSITES" or "SITESETUP"?

Or only if the switch value is "SITESETUP"?

Since "GETSITES" has no break, I'm thinking yes, but am not sure.


UPDATE

I guess the way I should have worded my question as:

Are these two code fragments semantically equivalent?

  • fragment 1

    case 0:
    case 1:
        // bla bla bla;
        break;
    
  • fragment 2(pseudo code)

    case 0, 1:
        // bla bla bla;
        break;
    
Ken Kin
  • 4,503
  • 3
  • 38
  • 76
B. Clay Shannon-B. Crow Raven
  • 8,547
  • 144
  • 472
  • 862
  • 17
    why not give it a try? It would have taken less time/effort for you to try this out than to ask here.. – Mike Dinescu Mar 01 '13 at 18:21
  • 1
    You don't have an "empty" case you have two cases that display the exact same message. Since it seems you didn't even run this code to verify your theory I have to issue a downvote. Good questions are those questions the author researches before asking. – Security Hound Mar 01 '13 at 18:47
  • True, I could have done it in another "throwaway" project - this particular one is not so easy, though. I have to make changes, add debug statements, copy the new build to the handheld, run it from there, see if the debug statements display, etc. – B. Clay Shannon-B. Crow Raven Mar 01 '13 at 19:19
  • OK, I added a MessageBox.Show() in that code, and sure enough, the "empty" case is handled by the one below it. – B. Clay Shannon-B. Crow Raven Mar 01 '13 at 20:10
  • possible duplicate of [Switch statement fallthrough in C#?](http://stackoverflow.com/questions/174155/switch-statement-fallthrough-in-c) – WiredPrairie Mar 01 '13 at 21:42
  • 1
    Hi Clay...with something and fundamental as this why not write a small console application to test this. Then if there's something you aren't comprehending about the outcome ask about that. Thanks. – Kev Mar 02 '13 at 17:23
  • 3
    Those fragments are not *equivalent* because the second one is not *legal*. – Eric Lippert Mar 04 '13 at 14:45

3 Answers3

7

What you are describing is having two labels for the same case. C# does allow this. You cannot, however, fall through to the next case statement in the same way that C allows, that is, your label cannot have some code, then fall through to the next case statement. That is forbidden and will cause a compilation error.

tvanfosson
  • 524,688
  • 99
  • 697
  • 795
  • Yes, I know you can do "case 0, 1, 2: Bla;break:" My question is, do the empty cases just get ignored (if so, why do they exist - just to show you have considered them?) – B. Clay Shannon-B. Crow Raven Mar 01 '13 at 19:21
  • @ClayShannon Consider the case where you have two, non-default options that are treated identically with respect to a particular switch statement. In that case you can either repeat the code for each case or use two (or more) labels that map onto the same code. Omitting the label would cause the (incorrect) default label to be taken. – tvanfosson Mar 01 '13 at 19:27
  • Okay, but I thought the syntax for that was "case 0,1,2: Bla;break;" not "case 0: case 1: case 2: Bla;break;" – B. Clay Shannon-B. Crow Raven Mar 01 '13 at 19:41
  • @ClayShannon - no, your first example isn't valid syntax in C#. A case statement can have one and only one constant value, http://msdn.microsoft.com/en-us/library/vstudio/06tc147t.aspx – tvanfosson Mar 01 '13 at 20:09
6

Do empty case statements in C# combine with the next non-empty one?

I originally said:

The question supposes a falsehood. There is no such thing as an empty switch section in a legal C# program.

That is not quite true. The C# specification requires that a switch section contain at least one statement, but the implementation actually does not.

I emend my statement as follows:

The question supposes that there is an empty switch section (note that switch sections are not statements), but there can only be an empty switch section in a very unusual situation. First off, let's clearly describe the anatomy of a switch statement.

When you have:

switch(x) 
{ 
   case 1: 
   case 2: 
       Console.WriteLine("Hello");
       break;
}

there is only one switch section. There is no "empty section" following case 1; a section consists of all the case clauses followed by zero or more statements. (The spec requires one or more statements but the implementation actually allows zero statements.) The statement list must have a non-reachable endpoint.

The only way for there to be an empty statement list whose end point is not reachable inside a switch section is for the switch section itself to be unreachable. There are two ways that can happen. Either the entire switch can be unreachable, or the switch can be switching on a constant. In short, the only way to make an empty switch section is either:

switch(1) { case 2: }

or

if (false) switch(x) { case 2: }

Neither is legal according to the spec, but the C# compiler allows both. Fortunately this is a pretty harmless bug.

In both cases the end point of the section is not reachable and so the empty section is reachable. But it is never the case that there is an empty section between cases.

Eric Lippert
  • 647,829
  • 179
  • 1,238
  • 2,067
  • Thanks for the terminology ***non-reachable endpoint***! – Ken Kin Mar 01 '13 at 23:06
  • @KenKin: You're welcome. In case it is not clear, by having a "non reachable endpoint" I mean that a statement must be a `break`, `continue`, `goto`, `throw` or `return` -- all of which transfer control elsewhere -- or a provable infinite loop, like `while(true) {}`. – Eric Lippert Mar 01 '13 at 23:11
  • Out of curiosity, is `switch (1) { case 2: }` a legal statement in C#? It compiles without error in VS2012, but it appears to have a switch section with an empty statement list. (I understand that `switch (1) { case 2: ; }` would be legal because the statement list is unreachable, and I realize that the behavior of unreachable empty code is not especially important, but I'm curious whether I'm misreading the spec or whether the compiler differs from the spec here.) – Quartermeister Mar 05 '13 at 20:10
  • @Quartermeister: That is awesome; you have found a counterexample to my claim. I never even thought to consider reachability considerations of constant expression switches despite the fact that I myself rewrote the code to handle them in... 2005? Something like that. Anyway, yes, that is legal according to the spec. As is `if (false) switch(x) { case 1: }`. Nice! – Eric Lippert Mar 05 '13 at 21:50
  • 2
    Thanks! But I guess I'm misreading the spec then, because it defines _switch-section: switch-labels statement-list_ and _statement-list: statement | statement-list statement_, so I would think that `switch (1) { case 2: }` shouldn't even parse because the _statement-list_ is missing. – Quartermeister Mar 05 '13 at 22:25
  • 3
    Good heavens you are right again. This *is* a bug. The spec requires that the switch section be non-empty. I can't believe I've never noticed that before. – Eric Lippert Mar 05 '13 at 22:37
3

Based on testing, you can do the following:

switch(i)
{
    case 0:
    case 1:
    case 2:
        doSomething();
        break;
    default:
        doNothing();
        break;
}

but you cannot:

switch(i)
{
   case 0:
      doSomething();
   case 1:
      doSomethingElse();
      break;
   default:
      doNothing();
      break;
}

So, the answer is, YES, you can stack multiple cases together, but you cannot let control run from one case to another.

David Hope
  • 2,216
  • 16
  • 32