5
#include<stdio.h>

void main()
{
    int a = 4;
    switch (a)
    {
        case 4:
            int res = 1;
            printf("%d",res);
        break;

    }
}

When I compiled this code with gcc I got error

root@ubuntu:/home/ubuntu# gcc test.c -o t
test.c: In function ‘main’:
test.c:9:4: error: a label can only be part of a statement and a declaration is not a statement
    int res = 1;

But when I add ; like case 4:; I can compile my code.

What is the problem and why ; fix that?

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
yokjc232
  • 91
  • 5

3 Answers3

8

Opposite to C++, in C declarations are not statements and labels may precede only statements.

Placing a null statement after the label

case 4:;

you made that the label does not precede now a declaration.

Another approach is to use a compound statement after the label and to place the declaration inside the compound statement like

    case 4:
    {  
        int res = 1;
        printf("%d",res);
        break;
    }
ryyker
  • 22,849
  • 3
  • 43
  • 87
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
6

The problem is in your error message: labels can only be attached to statements and a declaration is not a statement.

Seeing N1570 6.8.2 Compound statement, there are declaration and statement enumerated separately, and it is suggesting that they are different things.

Syntax
1     compound-statement:
          { block-item-listopt }

      block-item-list:
          block-item
          block-item-list block-item

      block-item:
          declaration
          statement

The ; in case 4:; is a null statement (defined in N1570 6.8.3 Expression and null statements), which is a statement, and thus it is allowed.

MikeCAT
  • 73,922
  • 11
  • 45
  • 70
3

What is the problem and why ; fix that?

The problem is just what the error message says. Your case 4: is a label. Labels identify the immediately-following statement, and therefore must immediately precede a statement. Declarations such as int res = 1; are not statements.

On the other hand, adding a semicolon creates an empty statement, which, as its name implies, is a statement, and therefore can be labeled. That's why it solves the problem.

With that said, I'd rate the semicolon solution poor style. I'd also rate declaring a variable whose enclosing block is the body of a switch as poor style, and that one can bite you in other ways, too. Consider instead moving the declaration of res outside the switch ...

int a = 4;
int res = 1;
switch (a) {
    case 4:
        printf("%d",res);
    break;
}

... or enclosing it in an inner block (which is a compound statement, and therefore can be labeled) ...

int a = 4;
switch (a) {
    case 4: {
        int res = 1;
        printf("%d",res);
        break;
    }
}

.

John Bollinger
  • 160,171
  • 8
  • 81
  • 157