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 0x1006h: No utilizar la instrucción goto

Estructuras de control y flujo (0x10XX)

Universidad Nacional de Río Negro

0x1006h: No utilizar la instrucción goto

Enunciado normativo

NO DEBE usarse la instrucción goto en el código de la cátedra. Toda repetición o salto condicional DEBE expresarse con las estructuras de control estándar (if, for, while, do-while, switch).

¿Por qué existe esta regla?

El problema

goto permite saltar a cualquier etiqueta del mismo cuerpo, hacia adelante o hacia atrás, sin pasar por las condiciones que las otras estructuras imponen. El flujo deja de ser un árbol y se vuelve un grafo: para saber qué se ejecuta después de una línea hay que buscar todas las etiquetas y todos los saltos.

Ese costo lo paga cada lector, cada vez. El teorema de la programación estructurada de Böhm–Jacopini demuestra que todo programa con goto puede reescribirse con secuencia, selección e iteración; por lo tanto el goto no aporta poder expresivo, solo oscurecimiento.

Consecuencias de violarla

Tipo de consecuenciaEfecto concreto
Código espaguetiSaltos cruzados que hacen imposible seguir el flujo linealmente.
DepuraciónEl contador de programa salta sin relación aparente con la línea previa.
MantenibilidadMover una sentencia puede romper una etiqueta distante.
InicializaciónUn salto hacia atrás puede reintroducir un estado ya procesado.

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

ISO/IEC 9899:2011 §6.8.6.1 define goto; el estándar lo permite, y de hecho admite el patrón de liberación centralizada. La cátedra adopta la prohibición general para forzar el razonamiento estructurado en el curso introductorio. La regla más específica 0x1011h: Prohibición de saltos no estructurados goto fuera del patrón canónico de liberación de recursos admite una única excepción acotada; ante cualquier duda, consultar con la cátedra.

Alcance y excepciones

Ejemplos exhaustivos

❌ Contraejemplo 1 — goto simulando un lazo

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

Por qué falla: un lazo for expresa lo mismo en tres líneas. Acá el flujo depende de dos etiquetas y tres saltos; agregar un continue equivalente requiere otra etiqueta.

❌ Contraejemplo 2 — goto cruzando la inicialización

goto saltar;
int total = 0;
saltar:
    printf("%d\n", total);

Por qué falla: el salto omite la inicialización y total se lee con un valor indeterminado. Es comportamiento indefinido (ISO/IEC 9899:2011 §6.2.4).

✅ Ejemplo conforme 1 — lazo estructurado equivalente

for (int i = 0; i < n; i++)
{
    procesar(valores[i]);
}

El encabezado reúne inicialización, cota e incremento; no hay etiquetas ni saltos que rastrear.

✅ Ejemplo conforme 2 — salida temprana estructurada

bool procesar_todo(const int valores[], size_t n)
{
    for (size_t i = 0; i < n; i++)
    {
        if (!procesar(valores[i]))
        {
            return false;
        }
    }
    return true;
}

El retorno anticipado reemplaza al goto de error; es una salida legítima dentro de una función corta (ver 0x2001h: Las funciones deben usar cláusulas de guarda y retornos anticipados para reducir la anidación profunda).

⚠️ Casos límite

Cómo detectarla

HerramientaComandoSeñal
gaffgaff check archivo.cRegla 0x1006h: uso de goto.
Búsquedagrep -n "goto" archivo.cToda aparición es una violación.
gccgcc -Wall -WextraNo la señala: goto es C válido.

Checklist de autocontrol

Reglas relacionadas

Antipatrón: Uso de salto goto hacia atrás vulnerando programación estructurada

Síntoma en el código del estudiante

Un goto salta hacia atrás a una etiqueta anterior para repetir un bloque, simulando un lazo:

repetir:
    /* ... */
    goto repetir;

Diagnóstico

Mecanismo del defecto

goto transfiere el control a la etiqueta sin pasar por ninguna estructura (ISO/IEC 9899:2011 §6.8.6.1). Un salto hacia atrás reconstruye a mano un lazo: la condición de corte queda dispersa en el cuerpo y la cantidad de repeticiones no se lee en ningún encabezado. El flujo deja de ser un árbol y se vuelve un grafo.

Consecuencia observable

El código funciona, pero cada lector debe rastrear los saltos para entender cuántas veces se repite el bloque y bajo qué condiciones. Un cambio en el cuerpo puede volver el salto infinito o inalcanzable, y el compilador no lo ayuda. Es el llamado “código espagueti” que la programación estructurada busca evitar.

Fundamento en el estándar C11

ISO/IEC 9899:2011 §6.8.6.1 define goto y admite cualquier dirección. El teorema de Böhm–Jacopini garantiza que todo programa con goto puede reescribirse con secuencia, selección e iteración. La cátedra prohíbe el uso general (regla 0x1006h) y tolera solo el salto hacia adelante a un bloque de limpieza (regla 0x1011h).

Corrección idiomática

❌ Código con el antipatrón
int i = 0;
repetir:
    if (i >= n)
    {
        goto fin;
    }
    procesar(valores[i]);
    i++;
    goto repetir;
fin:
    return 0;
✅ Código refactorizado
for (int i = 0; i < n; i++)
{
    procesar(valores[i]);
}
return 0;

El for reúne inicialización, cota e incremento; no hay etiquetas ni saltos que rastrear y agregar un corte equivale a modificar la condición.

Errores típicos al compilar o ejecutar

No hay error de compilación. Con -Wall, GCC y Clang pueden no advertir nada.

El riesgo es de mantenimiento: si se olvida el incremento o el goto
condicional, el lazo se vuelve infinito. Un cambio en el cuerpo puede
dejar la etiqueta fin inalcanzable.

Checklist de verificación

Reglas relacionadas