Variablendeklaration nach goto Label

Lesezeit: 3 Minuten

Krishnabhadras Benutzeravatar
Krishnabhadra

Heute habe ich eine interessante Sache gefunden. Ich wusste nicht, dass man nach einem goto-Label keine Variable deklarieren kann.

Kompilieren des folgenden Codes

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

gibt Fehler wie

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

Was ist nun die Logik dahinter? das habe ich gehört Innerhalb der case-Anweisungen von switch können keine Variablen erstellt werden. Da sich JUMP innerhalb des gleichen Geltungsbereichs (in meinem Fall der Geltungsbereich der Hauptfunktion) der goto-Anweisung befindet, glaube ich, dass der Geltungsbereich hier kein Problem darstellt. Aber warum erhalte ich dann diesen Fehler?

Die Syntax erlaubt es einfach nicht. §6.8.1 Beschriftete Aussagen:

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

Beachten Sie, dass es keine Klausel gibt, die eine „beschriftete Deklaration“ zulässt. Es ist einfach nicht Teil der Sprache.

Sie können dies natürlich mit einer leeren Anweisung trivial umgehen.

JUMP:;
int a = 0;

Sie möchten ein Semikolon nach dem Label wie folgt:

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

Dann wird Ihr Code korrekt für den C99-Standard kompiliert, mit gcc -Wall -std=c99 -c krishna.c (Ich verwende GCC 4.6 auf Debian/Sid/AMD64).

Eine einfache Erklärung, außer dass die Spezifikation dies nicht sagt, ist, dass der Compiler erwartet, dass der Code nach dem goto etwas ist, das in eine Operation kompiliert wird, von der er dann den Offset berechnen kann, und tritt, weil Ihre Variablendeklaration keine Anweisung ist /block, dass es in einen solchen Offset kompilieren kann.

  • Der Standard (und gcc) erlaubt a Zusammengesetzte Aussage nach einem Etikett, dh, JUMP: { int a = 0; printf("%d", a); }; Glauben Sie, dass eine solche Aussage zu einer Operation kompiliert wird?

    – tbrk

    10. September 2020 um 13:09 Uhr

Meine gcc-Version (4.4) gibt diesen Kompilierungsfehler aus:

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

. Diese Fehlermeldung sagt alles.

Benutzeravatar von COD3BOY
COD3BOY

Wenn Sie wissen, warum Sie keine Variablen innerhalb der case-Anweisung von switch erstellen können, ist es im Grunde der gleiche Grund, warum Sie dies auch nicht tun können. Als Lösung können Sie dies versuchen,

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

Michael Krelin - Benutzeravatar des Hackers
Michael Krelin – Hacker

Nun, zunächst sollten Sie konsequent sein. Es ist entweder LABEL oder label. Zweitens ist das Label ein Teil der Aussage und die Deklaration beantwortet die Beschreibung nicht ausreichend.

Sie können ersetzen LABEL: mit label: ; und dann ist es wahrscheinlicher zu kompilieren.

BEARBEITEN: Jetzt, da Sie Ihren Code vollständig bearbeitet haben, sollte es so sein JUMP: Ersetzt mit JUMP: ; 😉

Benutzeravatar von Jeegar Patel
Jeegar Patel

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

1417770cookie-checkVariablendeklaration nach goto Label

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy