goto Label 之后的变量声明

发布于 2024-12-19 16:38:20 字数 708 浏览 3 评论 0原文

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

Today I found one interesting thing. I didn't know that one can't declare a variable after a goto label.

Compiling the following code

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

gives errors like

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.)

Now what is the logic behind that? I heard that one cannot create variables inside the case statements of switch. Since JUMP is inside the same scope (the scope of main function, in my case) of the goto statement, I believe that scope is not an issue here. But then, why am I getting this error?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

余厌 2024-12-26 16:38:20

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

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

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

当然,您可以使用空语句轻松解决此问题。

JUMP:;
int a = 0;

The syntax simply doesn't allow it. §6.8.1 Labeled Statements:

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

Note that there is no clause that allows for a "labeled declaration". It's just not part of the language.

You can trivially work around this, of course, with an empty statement.

JUMP:;
int a = 0;
折戟 2024-12-26 16:38:20

您希望在标签后有一个分号,如下所示:

 #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 (我正在使用 GCC 4.6 Debian/Sid/AMD64)。

You want a semi-colon after the label like this:

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

Then your code compiles correctly for the C99 standard, with gcc -Wall -std=c99 -c krishna.c (I'm using GCC 4.6 on Debian/Sid/AMD64).

聽兲甴掵 2024-12-26 16:38:20

除了规范没有说的之外,简单的解释是编译器期望 goto 之后的代码编译成一个操作,然后可以计算该操作的偏移量,并且因为您的变量声明不是语句而被踢/block 它可以编译成这样的偏移量。

Simple explanation, other than the spec says not, is that the compiler is exepecting the code after the goto to be something that compiles into an operation which it can then calculate the offset of, and is kicking because your variable declaration isn't a statement/block that it can compile into such an offset.

蓦然回首 2024-12-26 16:38:20

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

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

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

My gcc version (4.4) is giving this compile error:

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

. This error-message says it all.

赠意 2024-12-26 16:38:20

如果您知道为什么不能在 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
}

If you know why you can't create variables inside case statement of switch, basically its the same reason why you cant do this too. As a fix, you can try this,

#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
}
故笙诉离歌 2024-12-26 16:38:20

嗯,首先你应该保持一致。它是 LABELlabel。其次,标签是声明的一部分,声明并不能充分回答描述。

您可以将 LABEL: 替换为 label: ; ,这样就更容易编译。

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

Well, first you should be consistent. It's either LABEL or label. Second, label is a part of the statement and the declaration doesn't answer the description enough.

You can replace LABEL: with label: ; and then it is likelier to compile.

EDIT: Now that you edited your code all over, it should be JUMP: replaced with JUMP: ; ;-)

[旋木] 2024-12-26 16:38:20
#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);
}
#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);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文