goto Label后的variables声明

今天我发现了一件有趣的事情。 我不知道在goto标签之后不能声明variables。

编译下面的代码

#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语句里面不能创buildvariables 。 由于JUMP在goto语句的相同范围内(在我的情况下是主函数的范围),我认为范围在这里不是问题。 但是,为什么我得到这个错误?

语法根本不允许它。 §6.8.1标记语句:

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

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

当然,你可以用一个空的语句来解决这个问题。

 JUMP:; int a = 0; 

你想要这样的标签后面的分号:

  #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)。

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

 tc:7: error: a label can only be part of a statement and a declaration is not a statement 

。 这个错误信息说明了一切。

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

那么,首先你应该是一致的。 它是LABELlabel 。 其次,标签是声明的一部分,声明不足以回答描述。

你可以用LABEL:replaceLABEL: 然后编译才更可能。

编辑:现在你编辑你的代码全部,它应该是JUMP:JUMP: ;replaceJUMP: ; 😉

如果你知道为什么你不能在switch语句中创buildvariables,基本上它也是你不能这样做的原因。 作为一个修复,你可以试试这个,

 #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 } 

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

 #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); }