转到标签后的变量声明

时间:2011-12-05 11:09:21

标签: c goto variable-declaration

今天我发现了一件有趣的事情。我不知道在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函数的范围),我认为范围在这里不是问题。但是,为什么我会收到这个错误?

8 个答案:

答案 0 :(得分:84)

语法根本不允许。 §6.8.1标签声明:

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

请注意,没有任何条款允许“标记声明”。它只是语言的一部分。

当然,你可以通过一个空的陈述来解决这个问题。

JUMP:;
int a = 0;

答案 1 :(得分:13)

你想在标签后面加一个分号:

 #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上使用GCC 4.6)。

答案 2 :(得分:6)

我的gcc版本(4.4)给出了这个编译错误:

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

。这条错误消息说明了一切。

答案 3 :(得分:6)

除了规范没有说明之外,简单的解释是编译器在goto之后编写代码来编译成一个操作,然后它可以计算偏移量,并且因为你的变量声明不是'一个语句/块,它可以编译成这样的偏移量。

答案 4 :(得分:2)

嗯,首先你应该保持一致。它可以是LABELlabel。其次,标签是声明的一部分,声明不足以回答说明。

您可以将LABEL:替换为label: ;,然后编译就更有可能。

编辑:现在您已经编辑了所有代码,应将JUMP:替换为JUMP: ;; - )

答案 5 :(得分: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
}

答案 6 :(得分:1)

这不是因为标签本身,而是因为已有语句(goto和printf)。最新标准似乎允许在任意位置进行变量声明,但并非每个编译器都完全符合标准。此外,标识符在C中区分大小写,并且您的标签在两个位置都必须相同。

答案 7 :(得分: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);
}