Declaración de variable después de goto Label

5 minutos de lectura

Declaracion de variable despues de goto Label
krishnabhadra

Hoy encontré una cosa interesante. No sabía que no se puede declarar una variable después de una etiqueta goto.

Compilando el siguiente código

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

da errores como

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

Ahora, ¿cuál es la lógica detrás de eso? escuché eso uno no puede crear variables dentro de las declaraciones de caso de interruptor. Dado que JUMP está dentro del mismo alcance (el alcance de la función principal, en mi caso) de la instrucción goto, creo que el alcance no es un problema aquí. Pero entonces, ¿por qué recibo este error?

La sintaxis simplemente no lo permite. §6.8.1 Declaraciones etiquetadas:

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

Tenga en cuenta que no hay ninguna cláusula que permita una “declaración etiquetada”. Simplemente no es parte del idioma.

Puede solucionar esto trivialmente, por supuesto, con una declaración vacía.

JUMP:;
int a = 0;

Desea un punto y coma después de la etiqueta como este:

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

Entonces su código se compila correctamente para el estándar C99, con gcc -Wall -std=c99 -c krishna.c (Estoy usando GCC 4.6 en Debian/Sid/AMD64).

La explicación simple, aparte de que la especificación dice que no, es que el compilador está esperando que el código después del goto sea algo que se compile en una operación de la que luego puede calcular el desplazamiento, y está pateando porque su declaración de variable no es una declaración /block que puede compilar en tal compensación.

  • El estándar (y gcc) permite un declaración compuesta después de una etiqueta, es decir, JUMP: { int a = 0; printf("%d", a); }; ¿Considera que tal declaración se compila en una operación?

    – tbrk

    10 de septiembre de 2020 a las 13:09

Mi versión de gcc (4.4) está dando este error de compilación:

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

. Este mensaje de error lo dice todo.

Bueno, primero debes ser consistente. es cualquiera LABEL o label. En segundo lugar, la etiqueta es parte de la declaración y la declaración no responde lo suficiente a la descripción.

Puedes reemplazar LABEL: con label: ; y entonces es más probable compilar.

EDITAR: Ahora que editaste tu código por completo, debería ser JUMP: reemplazadas con JUMP: ; 😉

  • lo siento por eso… Cambié a JUMP para que no haya confusión… Y por favor considere esto como un programa de prueba fácil que reproduce lo que estoy preguntando aquí… Esas declaraciones printf no significan nada.

    – Krishnabhadra

    5 de diciembre de 2011 a las 11:17

  • Esta bien. printfNo significa nada, te señalé el problema (y la solución) independientemente de printfs.

    – Michael Krelin – hacker

    5 de diciembre de 2011 a las 11:18

  • Todos ustedes están diciendo: 1) Una etiqueta debe ser parte de una declaración. Y en C una declaración no es un enunciado. 2) El error no tiene nada que ver con el alcance (que es lo que pensé primero), ¿correcto?

    – Krishnabhadra

    5 de diciembre de 2011 a las 11:36

  • No, no se trata del alcance.

    – Michael Krelin – hacker

    5 de diciembre de 2011 a las 11:38

  • Sí, lo más probable. Puede haber diferentes problemas al omitir la inicialización de variables debido al salto, pero debería obtener un diagnóstico decente para eso. Y si lo hace, simplemente separe la declaración y la inicialización.

    – Michael Krelin – hacker

    5 de diciembre de 2011 a las 11:41

Declaracion de variable despues de goto Label
Basile Starynkevitch

Si sabe por qué no puede crear variables dentro de la declaración de cambio de caso, básicamente es la misma razón por la que no puede hacer esto también. Como solución, puedes probar esto,

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

  • lo siento por eso… Cambié a JUMP para que no haya confusión… Y por favor considere esto como un programa de prueba fácil que reproduce lo que estoy preguntando aquí… Esas declaraciones printf no significan nada.

    – Krishnabhadra

    5 de diciembre de 2011 a las 11:17

  • Esta bien. printfNo significa nada, te señalé el problema (y la solución) independientemente de printfs.

    – Michael Krelin – hacker

    5 de diciembre de 2011 a las 11:18

  • Todos ustedes están diciendo: 1) Una etiqueta debe ser parte de una declaración. Y en C una declaración no es un enunciado. 2) El error no tiene nada que ver con el alcance (que es lo que pensé primero), ¿correcto?

    – Krishnabhadra

    5 de diciembre de 2011 a las 11:36

  • No, no se trata del alcance.

    – Michael Krelin – hacker

    5 de diciembre de 2011 a las 11:38

  • Sí, lo más probable. Puede haber diferentes problemas al omitir la inicialización de variables debido al salto, pero debería obtener un diagnóstico decente para eso. Y si lo hace, simplemente separe la declaración y la inicialización.

    – Michael Krelin – hacker

    5 de diciembre de 2011 a las 11:41

Declaracion de variable despues de goto Label
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);
}

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad