Waarom krijg ik “een label kan alleen deel uitmaken van een statement en een declaratie is geen statement” als ik een variabele heb die na een label wordt geïnitialiseerd?

Ik heb de volgende vereenvoudigde code:

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

Ik krijg een foutmelding omdat er een nieuwe variabele wordt gedeclareerd na het label. Als ik de inhoud (voornamelijk initialisatie) na het label in een {} blok zet, lukt het compileren.

Ik denk dat ik de reden voor de blokkering begrijp in het geval van een overstap, maar waarom zou het van toepassing zijn in het geval van een label?

Deze fout komt van een gcc-compiler


Antwoord 1, autoriteit 100%

De taalstandaard staat het gewoon niet toe. Labels kunnen alleen worden gevolgd door statements, en declaraties tellen niet mee als statements in C. De eenvoudigste manier om dit te omzeilen is door een lege instructie achter uw label in te voegen, waardoor u niet langer de scope hoeft bij te houden zoals u dat zou moeten doen. binnen een blok.

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

Antwoord 2, autoriteit 20%

Dit is een erfenis van de C Grammatica. A LABEL (Cleanup:) is niet toegestaan ​​om onmiddellijk voor een -verklaring (zoals char *str ...;), alleen vóór een -aanduiding (printf(...);). In C89 was dit geen grote moeite omdat verklaringen slechts aan het begin van een blok konden verschijnen, zodat u het label altijd een beetje kunt verplaatsen en het probleem kunt vermijden. In C99 kunt u aangiften en code mixen, maar u kunt nog steeds een label niet onmiddellijk voor een aangifte plaatsen.

U kunt onmiddellijk na de darm van het label een puntkomma plaatsen (zoals gesuggereerd door Renan) om daar een lege verklaring te maken; Dit is wat ik zou doen in de machine-gegenereerde code. Als alternatief moet hij de aangifte naar de bovenkant van de functie wijzigen:

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

Other episodes