The C99 standard is not explicit about this, but taking all facts together, it is perfectly valid.
A case
and default
label are equivalent to a goto
label. See 6.8.1 Labeled statements. Especially interesting is 6.8.1.4, which enables the already mentioned Duff's Device:
Any statement may be preceded by a
prefix that declares an identifier as
a label name. Labels in themselves do
not alter the flow of control, which
continues unimpeded across them.
Edit: The code within a switch is nothing special; it is a normal block of code as in an if
-statement, with additional jump labels. This explains the fall-through behaviour and why break
is necessary.
6.8.4.2.7 even gives an example:
switch (expr)
{
int i = 4;
f(i);
case 0:
i=17;
/*falls through into default code */
default:
printf("%d\n", i);
}
In the artificial program fragment 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.
The case constants must be unique within a switch statement:
6.8.4.2.3 The expression of each case label shall be an integer constant
expression and no two of the case
constant expressions in the same
switch statement shall have the same
value after conversion. There may be
at most one default label in a switch
statement.
All cases are evaluated, then it jumps to the default label, if given:
6.8.4.2.5 The integer promotions are performed on the controlling
expression. The constant expression in
each case label is converted to the
promoted type of the controlling
expression. If a converted value
matches that of the promoted
controlling expression, control jumps
to the statement following the matched
case label. Otherwise, if there is a
default label, control jumps to the
labeled statement. If no converted
case constant expression matches and
there is no default label, no part of
the switch body is executed.