Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Regla 0x1011h: Prohibición de saltos no estructurados goto fuera del patrón canónico de liberación de recursos

Estructuras de control y flujo (0x10XX)

Universidad Nacional de Río Negro

0x1011h: Prohibición de saltos no estructurados goto fuera del patrón canónico de liberación de recursos

Enunciado normativo

ESTÁN PROHIBIDOS los saltos goto hacia atrás, los que simulan lazos no estructurados y los que apuntan a etiquetas intermedias. SÓLO SE TOLERA el goto hacia adelante que salta a un bloque terminal único de liberación de recursos.

¿Por qué existe esta regla?

El problema

Un goto hacia atrás reconstruye a mano un lazo que el lenguaje ya ofrece y obliga a rastrear el salto para saber cuántas veces se repite el código. Un salto a una etiqueta intermedia fragmenta el flujo en pedazos que no corresponden a ninguna estructura, y puede provocar dobles liberaciones.

El goto hacia adelante con un único bloque de limpieza es distinto: su forma es reconocible, usa una sola etiqueta, salta siempre en la misma dirección y la liberación vive en un único lugar. Por eso es el único patrón tolerado.

Consecuencias de violarla

Tipo de consecuenciaEfecto concreto
Código espaguetiSaltos cruzados que impiden leer el flujo linealmente.
Doble liberaciónUn salto a una etiqueta intermedia puede liberar dos veces.
MantenibilidadMover código puede dejar una etiqueta inalcanzable.

Fundamento en el estándar y en la cátedra

ISO/IEC 9899:2011 §6.8.6.1 define goto; es legal en cualquier dirección. La cátedra prohíbe el uso general en 0x1006h: No utilizar la instrucción goto y deja esta excepción acotada para el patrón de limpieza, apoyada en 0x300Fh: Liberá la memoria en el orden inverso a su asignación y 0x3002h: Liberá siempre la memoria dinámica y asigná NULL al puntero para mitigar punteros colgantes.

Alcance y excepciones

Ejemplos exhaustivos

❌ Contraejemplo 1 — goto hacia atrás simulando un lazo

int i = 0;
repetir:
    if (i < n)
    {
        procesar(valores[i]);
        i++;
        goto repetir;
    }

Por qué falla: el for equivalente es más corto y declara el avance en el encabezado. El salto hacia atrás es exactamente el uso prohibido.

❌ Contraejemplo 2 — dos etiquetas intermedias de limpieza

if (paso_uno() != 0)
{
    goto error_uno;
}
if (paso_dos() != 0)
{
    goto error_dos;
}
error_dos:
    liberar_dos();
error_uno:
    liberar_uno();

Por qué falla: las etiquetas intermedias obligan a razonar el orden de caída y pueden liberar dos veces. El patrón canónico usa un único bloque terminal.

✅ Ejemplo conforme 1 — sin goto, con guardas

FILE *archivo = fopen(ruta, "r");
if (archivo == NULL)
{
    return false;
}
int *datos = malloc(TAMANO * sizeof(*datos));
if (datos == NULL)
{
    fclose(archivo);
    return false;
}

Con pocos recursos ni hace falta goto: cada guarda libera lo suyo antes de salir. Es la salida preferida cuando la función es corta.

✅ Ejemplo conforme 2 — goto hacia adelante a un único cleanup

bool exito = false;
int *datos = malloc(TAMANO * sizeof(*datos));
if (datos == NULL)
{
    goto cleanup;
}
/* ... usar datos ... */
exito = true;
cleanup:
    if (!exito)
    {
        free(datos);
        datos = NULL;
    }
    return exito;

Una sola etiqueta al final, siempre hacia adelante y con toda la liberación centralizada. Es el patrón canónico tolerado.

⚠️ Casos límite

Cómo detectarla

HerramientaComandoSeñal
gaffgaff check archivo.cRegla 0x1011h: goto no canónico.
Búsquedagrep -n "goto" archivo.cSaltos hacia atrás o etiquetas intermedias.
Revisión manualMás de una etiqueta o salto hacia atrás en la función.

Checklist de autocontrol

Reglas relacionadas