samuelbrody1249
samuelbrody1249

Reputation: 4767

Case statement with braces

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

Answers (3)

Luis Colorado
Luis Colorado

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

John Bollinger
John Bollinger

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

dbush
dbush

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

Related Questions