Warum bekomme ich “ein Label kann nur Teil einer Anweisung sein und eine Deklaration ist keine Anweisung”, wenn ich eine Variable habe, die nach einem Label initialisiert wird? [duplicate]

Lesezeit: 3 Minuten

Ich habe folgenden vereinfachten Code:

#include <stdio.h>
int main () 
{
    printf("Hello ");
    goto Cleanup;
Cleanup:
    char *str = "World\n";
    printf("%s\n", str);
}

Ich erhalte eine Fehlermeldung, weil nach dem Label eine neue Variable deklariert wird. Wenn ich den Inhalt (hauptsächlich Initialisierung) nach dem Label in einen {}-Block setze, ist die Kompilierung erfolgreich.

Ich glaube, ich verstehe den Grund für die Sperrung im Falle eines Wechsels, aber warum sollte es im Falle eines Labels gelten?

Dieser Fehler stammt von einem gcc-Compiler

  • Wenn Sie eine Variable unterhalb eines Labels definieren, müssen Sie den Gültigkeitsbereich der Variablen angeben. “` #include int main () { printf(“Hallo”); Gehe zu Bereinigung; Bereinigung: { char *str = “Welt\n”; printf(“%s\n”, str); } } “`

    – Wayne Chen

    17. Oktober 2017 um 2:10 Uhr


Der Sprachstandard lässt es einfach nicht zu. Auf Labels können nur Anweisungen folgen, und Deklarationen zählen in C nicht als Anweisungen. Der einfachste Weg, dies zu umgehen, besteht darin, eine leere Anweisung nach Ihrem Label einzufügen, was Sie davon befreit, den Gültigkeitsbereich so zu verfolgen, wie Sie es müssten innerhalb eines Blocks.

#include <stdio.h>
int main () 
{
    printf("Hello ");
    goto Cleanup;
Cleanup: ; //This is an empty statement.
    char *str = "World\n";
    printf("%s\n", str);
}

  • Wow, das ist bizarr. Was ist der Grund dafür?

    – Benutzer1952500

    28. August 2013 um 19:20 Uhr

  • Vor C99 mussten alle Deklarationen allen Anweisungen innerhalb eines Blocks vorangestellt werden, daher hätte es keinen Sinn gemacht, eine Deklaration mit einem Label zu versehen. C99 lockerte diese Einschränkung und erlaubte das Mischen von Deklarationen und Anweisungen innerhalb eines Blocks, aber die Syntax von a beschriftete Aussage wurde nicht geändert.

    – Keith Thompson

    28. August 2013 um 19:21 Uhr

  • Schenken ist generell nicht möglich Gründe dafür für diese Art von Sprachfehler. Die Grammatik ist so wie sie ist. Ich kann im C-Rationale-Dokument nachsehen … allerdings erst morgen … aber ich werde wahrscheinlich nichts finden.

    – zol

    28. August 2013 um 19:21 Uhr

  • @Zack: danke für die Erwähnung des C-Rationale-Dokuments. Es sieht interessant aus. Allerdings hätte in Abschnitt 6.8.6.1 (Die goto-Anweisung) das Beispiel, das er im letzteren Ansatz als bewährten Mechanismus verwendet, fehlschlagen sollen!

    – Benutzer1952500

    28. August 2013 um 19:33 Uhr

  • @pmor Wahrscheinlich, weil niemand daran gedacht oder es für die Mühe wert gehalten hat. Es ist nur ein Problem, wenn Sie verwenden goto Anweisungen, und die Problemumgehung ist trivial. Dort könnte eine Änderung in einer zukünftigen Ausgabe des Standards sein, aber ich habe keinen Vorschlag gefunden.

    – Keith Thompson

    25. März um 22:41 Uhr

Das ist eine Eigenart der C-Grammatik. EIN Etikett (Cleanup:) darf nicht unmittelbar vor a stehen Erklärung (wie zum Beispiel char *str ...;), nur vor a Aussage (printf(...);). In C89 war dies keine große Schwierigkeit, weil Erklärungen konnte nur ganz am Anfang eines Blocks erscheinen, sodass Sie die Beschriftung immer etwas nach unten verschieben und das Problem vermeiden konnten. In C99 können Sie Deklarationen und Code mischen, aber Sie können immer noch kein Label direkt vor eine Deklaration setzen.

Sie können direkt nach dem Doppelpunkt des Labels ein Semikolon setzen (wie von Renan vorgeschlagen), damit dort eine leere Anweisung steht; Dies ist, was ich in maschinell generiertem Code tun würde. Heben Sie alternativ die Deklaration an den Anfang der Funktion:

int main (void) 
{
    char *str;
    printf("Hello ");
    goto Cleanup;
Cleanup:
    str = "World\n";
    printf("%s\n", str);
    return 0;
}

1423030cookie-checkWarum bekomme ich “ein Label kann nur Teil einer Anweisung sein und eine Deklaration ist keine Anweisung”, wenn ich eine Variable habe, die nach einem Label initialisiert wird? [duplicate]

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

Privacy policy