今天我发现了一件有趣的事情。我不知道在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函数的范围),我认为范围在这里不是问题。但是,为什么我会收到这个错误?
答案 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)
答案 4 :(得分:2)
嗯,首先你应该保持一致。它可以是LABEL
或label
。其次,标签是声明的一部分,声明不足以回答说明。
您可以将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);
}