4

以下のコードをコンパイルすると、コンパイル エラーが発生します。

#include <stdio.h>
main()
{
    printf("Hello 123\n");
    goto lab;
    printf("Bye\n");

lab: int a = 10;
     printf("%d\n",a);
}

このコードをコンパイルすると、

test.c:8: error: a label can only be part of a statement and a declaration is not a statement

ラベルの最初の部分がステートメントである必要があるのはなぜですか?宣言ではないのはなぜですか?

4

3 に答える 3

6

この機能はラベル付きステートメントと呼ばれるため

C11 §6.8.1 ラベル付きステートメント

構文

labeled-statement:

identifier : statement

case constant-expression : statement

default : statement

簡単な修正は、null ステートメント (単一のセミコロン;)を使用することです。

#include <stdio.h>
int main()
{
    printf("Hello 123\n");
    goto lab;
    printf("Bye\n");

lab: ;         //null statement
    int a = 10;
    printf("%d\n",a);
}
于 2013-11-07T06:44:03.213 に答える
5

仕様によるとcで

§6.8.1 ラベル付きステートメント:

labeled-statement:
    identifier : statement
    case constant-expression : statement
    default : statement

c には、「ラベル付き宣言」を許可する句はありません。これを行うと動作します:

#include <stdio.h>
int main()
{
    printf("Hello 123\n");
    goto lab;
    printf("Bye\n");

lab: 
    {//-------------------------------
        int a = 10;//                 | Scope
        printf("%d\n",a);//           |Unknown - adding a semi colon after the label will have a similar effect
    }//-------------------------------
}

ラベルは、コンパイラにラベルを直接ラベルへのジャンプとして解釈させます。この種のコードでも同様の問題が発生します。

switch (i)
{   
   case 1:  
       // This will NOT work as well
       int a = 10;  
       break;
   case 2:  
       break;
}

ここでも、スコープ ブロック ( { }) を追加するだけで機能します。

switch (i)
{   
   case 1:  
   // This will work 
   {//-------------------------------
       int a = 10;//                 | Scoping
       break;//                      | Solves the issue here as well
   }//-------------------------------
   case 2:  
       break;
}
于 2013-11-07T06:43:02.723 に答える
0

シンプルな(しかし醜い)解決策:

lab: ; 
int a = 10;

空のステートメントにより、すべてが OK になります。
改行と前のスペース;は必要ありません。

于 2013-11-07T10:21:52.350 に答える