123 votes

Pourquoi est-ce que j'obtiens "une étiquette ne peut faire partie que d'une déclaration et une déclaration n'est pas une déclaration" si j'ai une variable qui est initialisée après une étiqu

J'ai le code simplifié suivant :

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

J'obtiens une erreur car une nouvelle variable est déclarée après l'étiquette. Si je place le contenu (principalement l'initialisation) après l'étiquette dans un bloc {}, la compilation réussit.

Je pense comprendre la raison du blocage dans le cas d'un interrupteur, mais pourquoi devrait-il être applicable dans le cas d'une étiquette ?

Cette erreur provient d'un compilateur gcc

171voto

Renan Gemignani Points 662

La norme linguistique ne le permet tout simplement pas. Les étiquettes ne peuvent être suivies que d'instructions, et les déclarations ne sont pas considérées comme des instructions en C. La façon la plus simple de contourner ce problème est d'insérer une instruction vide après votre étiquette, ce qui vous évite de devoir suivre la portée comme vous le feriez à l'intérieur d'un bloc.

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

32voto

Zack Points 44583

C'est une bizarrerie de la grammaire C. A étiquette ( Cleanup: ) n'est pas autorisé à apparaître immédiatement avant un déclaration (par exemple char *str ...; ), seulement avant un déclaration ( printf(...); ). En C89, ce n'était pas une grande difficulté car déclarations ne peut apparaître qu'au tout début d'un bloc, de sorte que vous pouvez toujours déplacer l'étiquette un peu plus bas et éviter le problème. En C99, vous pouvez mélanger les déclarations et le code, mais vous ne pouvez toujours pas placer une étiquette immédiatement avant une déclaration.

Vous pouvez mettre un point-virgule immédiatement après les deux-points du label (comme suggéré par Renan) pour qu'il y ait une déclaration vide à cet endroit ; c'est ce que je ferais dans un code généré par une machine. Une autre solution consiste à hisser la déclaration au sommet de la fonction :

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X