Reputation: 4767
Why does a case
statement allow declarations within braces but not without them?
For example, the following is not OK
switch (op->name) {
case 0:
int a = 2;
case 1:
int b = 3;
}
But the following is OK:
switch (op->name) {
case 0:
{int a = 2;}
case 1:
{int b = 3;}
}
What does the braces resolve that, without them, a declaration would be ambiguous to the compiler? To me (a beginner in C) it seems like each case statement should have an implied braces until the next case/default/end-of-switch, but that is obviously wrong!
Upvotes: 3
Views: 224
Reputation: 12688
Try this, and you'll get no error:
switch (op->name) {
case 0:; /* <--- that ; is essential, see below */
int a = 2;
case 1:; /* <--- the same here. */
int b = 3;
}
The problem is that the case
statement is a special case of statement, but a declaration is not a valid substitute of a statement, so a declaration is not allowed immediately after a case
label. But you can always end the case_statement with a semicolon (issuing a null statement), and put your declaration right after it.
Upvotes: 1
Reputation: 180715
Why does a case statement allow declarations within braces but not without them?
My compiler emits this error message:
error: a label can only be part of a statement and a declaration is not a statement
That's pretty clear I think. Labels, including case labels, are not considered independent statements or declarations, but rather components of statements. When control branches to a label, whether via a switch
or a goto
, it is the statement of which the label is a part to which the program jumps. Not to the label itself, which typically has no runtime representation.
Declarations such as int a;
are not statements, and labels cannot be part of declarations. On the other hand, blocks such as { int a; }
are statements, and as statements, they can have labels.
There's no fundamental underlying constraint here. It would have been possible for C syntax to have been defined differently, so that both of your examples were valid. It just wasn't.
Upvotes: 5
Reputation: 224207
The reason this is invalid:
switch (op->name) {
case 0:
int a = 2;
case 1:
int b = 3;
}
Is because you have a label (in this case a case
label) in front of a declaration. A label may only appear before a statement.
Using braces works because they are used to denote a compound statement, which is a particular type of statement, and a statement can immediately precede a label.
Formally, a label is part of a labeled statement. This is spelled out in section 6.8.1 of the C standard:
labeled-statement: identifier : statement case constant-expression : statement default : statement
Upvotes: 3