76

今日、私は1つの興味深いものを見つけました。gotoラベルの後に変数を宣言できないことを知りませんでした。

次のコードをコンパイルする

#include <stdio.h>
int main() {
    int x = 5;
    goto JUMP;
    printf("x is : %d\n",x);
JUMP:
    int a = 0;  <=== giving me all sorts of error..
    printf("%d",a);
}

次のようなエラーが発生します

temp.c: In function ‘main’:
temp.c:7: error: expected expression before ‘int’
temp.c:8: error: ‘a’ undeclared (first use in this function)
temp.c:8: error: (Each undeclared identifier is reported only once
temp.c:8: error: for each function it appears in.)

さて、その背後にある論理は何ですか?switchのcaseステートメント内に変数を作成できないと聞きました。JUMPはgotoステートメントと同じスコープ(私の場合はmain関数のスコープ)内にあるので、ここではスコープは問題ではないと思います。しかし、なぜこのエラーが発生するのですか?

4

7 に答える 7

99

構文は単にそれを許可していません。§6.8.1ラベル付きステートメント:

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

「ラベル付き宣言」を可能にする句がないことに注意してください。それは言語の一部ではありません。

もちろん、空のステートメントを使用して、これを簡単に回避できます。

JUMP:;
int a = 0;
于 2011-12-05T11:19:45.950 に答える
17

次のようなラベルの後にセミコロンが必要です。

 #include <stdio.h>
 int main() {
     int x = 5;
     goto JUMP;
     printf("x is : %d\n",x);
 JUMP: ;     /// semicolon for empty statement
     int a = 0; 
     printf("%d",a);
 }    

次に、コードはC99標準用に正しくコンパイルされますgcc -Wall -std=c99 -c krishna.c(私はDebian / Sid /AMD64でGCC4.6を使用しています)。

于 2011-12-05T11:21:06.323 に答える
7

仕様に記載されていない以外の簡単な説明は、コンパイラがgotoの後のコードを実行して、オフセットを計算できる操作にコンパイルし、変数宣言がステートメントではないためにキックしているということです。 /blockはそのようなオフセットにコンパイルできます。

于 2011-12-05T19:11:25.880 に答える
6

私のgccバージョン(4.4)はこのコンパイルエラーを出します:

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

。このエラーメッセージはそれをすべて示しています。

于 2011-12-05T11:14:23.257 に答える
2

switchのcaseステートメント内に変数を作成できない理由がわかっている場合は、基本的にこれも作成できないのと同じ理由です。修正として、これを試すことができます、

#include <stdio.h>
int main() {
    int x = 5;
    goto JUMP;
    printf("x is : %d\n",x);
JUMP:
    {                                              //Note this
       int a = 0;  // <=== no more error..
       printf("%d",a);
    }                                             //Note this
}
于 2011-12-05T11:24:44.110 に答える
2

さて、最初にあなたは一貫している必要があります。またはのいずれLABELlabelです。第二に、ラベルはステートメントの一部であり、宣言は説明に十分に答えていません。

に置き換えることができ、LABEL:そうlabel: ;すればコンパイルするのがより簡単になります。

編集:コード全体を編集したので、次のようにJUMP:置き換える必要がありますJUMP: ;;-)

于 2011-12-05T11:13:41.633 に答える
0
#include <stdio.h>
int main() {
    int x = 5;
    goto JUMP;
    printf("x is : %d\n",x);
JUMP:
    printf("Do anything after label but dont declare 
    anything. even empty statement will also work 
    because label can only be part of a statement");
    int a = 0;  
    printf("%d",a);
}
于 2011-12-05T12:23:34.217 に答える