c memory-management goto

C: stack memory, goto y "saltar al alcance del identificador con el tipo modificado variablemente",



memory-management (3)

Está prohibido por el estándar:

Norma C99, párrafo 6.8.6.1

Restricciones

[...] Una declaración goto no saltará fuera del alcance de un identificador que tenga un tipo modificado variablemente dentro del alcance de ese identificador.

Que es exactamente lo que está haciendo tu goto es decir, saltar desde fuera del alcance de apply dentro de él.

Puede usar la siguiente solución alternativa para limitar el alcance de apply :

if(0) goto error; { int apply[size]; give_values(apply,size); return 1; } error: return 0;

Descubrí que esto se niega a compilar:

int test_alloc_stack(int size){ if(0) goto error; // same issue whatever conditional is used int apply[size]; give_values(apply,size); return 1; error: return 0; }

El error que obtengo es: "saltar al alcance del identificador con el tipo de modificación variable". Eliminar la línea con "goto" y el salto al error resuelve los problemas.

Si uso la asignación dinámica para aplicar, entonces el problema también desaparece. Esto compila bien:

int test_alloc_heap(int size){ if(0) goto error; int * apply = calloc(sizeof(int),size); give_values(apply,size); free(apply); return 1; error : return 0; }

Que esta pasando ?


La declaracion:

int apply[size];

crea una matriz de longitud variable. Cuando sale del alcance, el compilador debe producir algún código que limpie la asignación para esa matriz. Saltarse dentro del alcance de tal objeto está prohibido, imagino porque algunas implementaciones podrían necesitar una inicialización que requeriría el código de limpieza, y si se salta al alcance, la inicialización se sostendría.

Si cambia a una asignación dinámica, la inicialización y la limpieza se convierten en su responsabilidad en lugar de en la del compilador.


Su goto hace omitir la línea que asigna apply (en tiempo de ejecución).

Puede resolver el problema de una de estas cuatro maneras:

1: Reescribe tu código para que no uses goto.

2: Mueva la declaración de apply a antes del goto .

3: Cambie el alcance para que el error: esté fuera del alcance de apply :

int test_alloc_stack(int size){ if(0) goto error; // same issue whatever conditional is used { int apply[size]; give_values(apply,size); return 1; } error: return 0; }

4: Cambie la declaración de variable para que su tamaño pueda determinarse en tiempo de compilación.