switch sirve que para gotoxy g++ goto

g++ - sirve - Declaración goto no puede cruzar definición de variable?



gotoxy c++ (2)

Supongamos que estos códigos compilados en g++ :

#include <stdlib.h> int main() { int a =0; goto exit; int *b = NULL; exit: return 0; }

g++ arrojará errores:

goto_test.c:10:1: error: jump to label ‘exit’ [-fpermissive] goto_test.c:6:10: error: from here [-fpermissive] goto_test.c:8:10: error: crosses initialization of ‘int* b’

Parece que el goto no puede cruzar la definición del puntero, pero gcc compila bien, nada se quejó.

Después de corregir el error, debemos declarar todos los punteros antes de cualquiera de la instrucción goto , es decir, debe declarar estos punteros aunque no los necesite en el presente (y la violación de algunos principios).

¿Cuál es la consideración de diseño de origen que g++ prohibió la declaración tail-goto útil?

Actualizar:

goto puede cruzar la declaración de variable ( cualquier tipo de variable, no limitada a puntero), pero excepto aquellas que obtuvieron un valor de inicialización . Si eliminamos la asignación NULL anterior, g++ guarda silencio ahora. Por lo tanto, si desea declarar variables entre goto -cross-area, no las inicialice (y aún viole algunos principios).


Goto no puede omitir definiciones de variables, porque esas variables no existirían después del salto, ya que la vida útil de la variable comienza en el punto de definición. La especificación no parece mencionar explícitamente que goto no debe hacer eso, pero está implícito en lo que se dice acerca de la duración de la variable.

Dado que el error menciona [-fpermissive] , puede convertirlo en advertencia especificando el indicador del compilador. Esto indica dos cosas. Que antes se permitía (la variable existiría, pero no se inicializaría después del salto) y que los desarrolladores de gcc creen que la especificación de la redacción implica que esto está prohibido (o implica que es un comportamiento indefinido que optaron por prohibir porque pueden).

El compilador solo verifica si la variable existe formalmente, no si se usa, de lo contrario los resultados serían bastante inconsistentes. Pero si ya no necesita la variable, puede terminar su vida útil, haciendo que el "tail-goto" sea viable:

int main() { int a =0; goto exit; { int *b = NULL; } exit: return 0; }

es perfectamente valido

En una nota lateral, está compilando con g++ , pero siempre que el archivo tenga la extensión .c , se considera C y no C ++. gcc y g++ difieren en algunos indicadores predeterminados, principalmente para la fase del vinculador, pero ambos compilan cualquier idioma instalado (C, C ++, ObjC, ObjC ++) según lo determine la extensión.


Hay una solución alternativa fácil para esos tipos primitivos como int :

// --- original form, subject to cross initialization error. --- // int foo = 0; // --- work-around form: no more cross initialization error. --- int foo; foo = 0;