C语言 如果我有一个在标签后初始化的变量,为什么会得到“标签只能是语句的一部分,而声明不是语句”?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18496282/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why do I get "a label can only be part of a statement and a declaration is not a statement" if I have a variable that is initialized after a label?
提问by user1952500
I have the following simplified code:
我有以下简化代码:
#include <stdio.h>
int main ()
{
printf("Hello ");
goto Cleanup;
Cleanup:
char *str = "World\n";
printf("%s\n", str);
}
I get an error because a new variable is declared after the label. If I put the content (mainly initialization) after the label in a {} block, compilation succeeds.
我收到一个错误,因为在标签之后声明了一个新变量。如果我将内容(主要是初始化)放在 {} 块中的标签之后,则编译成功。
I think I understand the reason for the block in case of a switch, but why should it be applicable in case of a label ?
我想我理解在 switch 的情况下阻止的原因,但为什么它应该适用于 label ?
This error is from a gcc compiler
此错误来自 gcc 编译器
回答by Renan Gemignani
The language standard simply doesn't allow for it. Labels can only be followed by statements, and declarations do not count as statements in C. The easiest way to get around this is by inserting an empty statement after your label, which relieves you from keeping track of the scope the way you would need to inside a block.
语言标准根本不允许这样做。标签后面只能跟语句,而声明在 C 中不能算作语句。解决这个问题的最简单方法是在标签后面插入一个空语句,这样您就不必像需要的那样跟踪作用域块内。
#include <stdio.h>
int main ()
{
printf("Hello ");
goto Cleanup;
Cleanup: ; //This is an empty statement.
char *str = "World\n";
printf("%s\n", str);
}
回答by zwol
This is a quirk of the C grammar. A label(Cleanup:) is not allowed to appear immediately before a declaration(such as char *str ...;), only before a statement(printf(...);). In C89 this was no great difficulty because declarationscould only appear at the very beginning of a block, so you could always move the label down a bit and avoid the issue. In C99 you can mix declarations and code, but you still can't put a label immediately before a declaration.
这是 C 语法的一个怪癖。一个标签(Cleanup:)是不允许出现立即之前的声明(如char *str ...;),只有前声明(printf(...);)。在 C89 中,这不是什么大问题,因为声明只能出现在块的最开始,所以你总是可以将标签向下移动一点并避免这个问题。在 C99 中,您可以混合使用声明和代码,但您仍然不能在声明之前立即放置标签。
You can put a semicolon immediately after the label's colon (as suggested by Renan) to make there be an empty statement there; this is what I would do in machine-generated code. Alternatively, hoist the declaration to the top of the function:
您可以在标签的冒号后立即放置一个分号(如 Renan 建议的那样),以便在那里有一个空语句;这就是我在机器生成的代码中所做的。或者,将声明提升到函数的顶部:
int main (void)
{
char *str;
printf("Hello ");
goto Cleanup;
Cleanup:
str = "World\n";
printf("%s\n", str);
return 0;
}

