Valid, but worthless syntax in switch-case?

Does this serve any purpose at all?

Yes. If instead of a statement, you put a declaration before the first label, this can make perfect sense:

switch (a) {
  int i;
case 0:
  i = f(); g(); h(i);
  break;
case 1:
  i = g(); f(); h(i);
  break;
}

The rules for declarations and statements are shared for blocks in general, so it's the same rule that allows that that also allows statements there.


Worth mentioning as well is also that if the first statement is a loop construct, case labels may appear in the loop body:

switch (i) {
  for (;;) {
    f();
  case 1:
    g();
  case 2:
    if (h()) break;
  }
}

Please don't write code like this if there is a more readable way of writing it, but it's perfectly valid, and the f() call is reachable.


Perhaps not the most useful, but not completely worthless. You may use it to declare a local variable available within switch scope.

switch (foo)
{
    int i;
case 0:
    i = 0;
    //....
case 1:
    i = 1;
    //....
}

The standard (N1579 6.8.4.2/7) has the following sample:

EXAMPLE    In the artificial program fragment

switch (expr)
{
    int i = 4;
    f(i);
case 0:
    i = 17;
    /* falls through into default code */
default:
    printf("%d\n", i);
}

the object whose identifier is i exists with automatic storage duration (within the block) but is never initialized, and thus if the controlling expression has a nonzero value, the call to the printf function will access an indeterminate value. Similarly, the call to the function f cannot be reached.

P.S. BTW, the sample is not valid C++ code. In that case (N4140 6.7/3, emphasis mine):

A program that jumps90 from a point where a variable with automatic storage duration is not in scope to a point where it is in scope is ill-formed unless the variable has scalar type, class type with a trivial default constructor and a trivial destructor, a cv-qualified version of one of these types, or an array of one of the preceding types and is declared without an initializer (8.5).


90) The transfer from the condition of a switch statement to a case label is considered a jump in this respect.

So replacing int i = 4; with int i; makes it a valid C++.