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 0x0013h: Detector de etiquetas de salto goto no alineadas al margen izquierdo

Sintaxis y formato visual (0x00XX)

Universidad Nacional de Río Negro

0x0013h: Detector de etiquetas de salto goto no alineadas al margen izquierdo

Enunciado normativo

Toda etiqueta de salto goto usada para gestión de errores DEBE situarse en la columna 1 (margen izquierdo), sin sangría, para que se reconozca de inmediato como destino de salto.

¿Por qué existe esta regla?

El problema

El compilador ignora la sangría: una etiqueta funciona igual en la columna 1 o indentada, de modo que nada en su forma la distingue de una sentencia. El margen izquierdo es la zona donde el ojo busca las definiciones de nivel superior; poner allí la etiqueta la separa del cuerpo sangrado y la señala como punto de entrada. Esta regla es el estilo de la única excepción tolerada por 0x1011h: Prohibición de saltos no estructurados goto fuera del patrón canónico de liberación de recursos al goto prohibido en 0x1006h: No utilizar la instrucción goto.

Consecuencias de violarla

Tipo de consecuenciaEfecto concreto
LegibilidadUna etiqueta indentada se confunde con una llamada o etiqueta de switch.
MantenibilidadAl mover bloques, es fácil arrastrar la etiqueta y romper la convención.
CompilaciónUna declaración inmediatamente después de la etiqueta es inválida en C11 (error: a label can only be part of a statement).

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

ISO/IEC 9899:2011 §6.8.1 exige que una etiqueta sea seguida por una sentencia, que una declaración no es; por eso cleanup: int x = 0; no compila en C11. §6.2.1 asigna a las etiquetas alcance de función. La cátedra adopta la alineación al margen como convención de lectura para el patrón de limpieza de 0x1011h: Prohibición de saltos no estructurados goto fuera del patrón canónico de liberación de recursos.

Alcance y excepciones

Aplica a etiquetas de goto (típicamente cleanup, error, salida). No aplica a case y default de un switch, que tienen su propia sangría. Si se admite un goto, su etiqueta va al margen (0x1006h: No utilizar la instrucción goto).

Ejemplos exhaustivos

❌ Contraejemplo 1 — Etiqueta indentada

static int procesar(FILE *archivo)
{
    char *buffer = malloc(TAMANO);
    if (buffer == NULL) {
        goto error;
    }
    free(buffer);
    return 0;

    error:
        free(buffer);
    return -1;
}

Por qué falla: error está sangrada y queda mezclada con el cuerpo del bloque, como si fuera una sentencia más. Además, el goto salta sobre la inicialización de las variables intermedias, tema de 0x1011h: Prohibición de saltos no estructurados goto fuera del patrón canónico de liberación de recursos.

❌ Contraejemplo 2 — Etiqueta con declaración pegada

    cleanup:
        free(buffer);

Por qué falla: la etiqueta está sangrada y, si se agregara una declaración justo después, no compilaría en C11 porque una etiqueta sólo puede preceder a una sentencia, no a una declaración.

✅ Ejemplo conforme 1 — Patrón de limpieza canónico

static int procesar(FILE *archivo)
{
    int resultado = -1;
    char *buffer = malloc(TAMANO);
    if (buffer == NULL) {
        goto cleanup;
    }
    resultado = 0;

cleanup:
    free(buffer);
    return resultado;
}

Por qué cumple: cleanup está en la columna 1 y la liberación es única, tanto por el camino feliz como por los errores, conforme a 0x1011h: Prohibición de saltos no estructurados goto fuera del patrón canónico de liberación de recursos.

✅ Ejemplo conforme 2 — Varias etiquetas alineadas

cleanup_archivo:
    fclose(archivo);

cleanup_buffer:
    free(buffer);

cleanup:
    return resultado;

Por qué cumple: todas las etiquetas comparten la columna 1, de modo que se leen como una cascada de limpieza en orden inverso, patrón compatible con 0x300Fh: Liberá la memoria en el orden inverso a su asignación.

⚠️ Casos límite

Cómo detectarla

HerramientaComandoSeñal
gaffgaff check archivo.cReporta una etiqueta que no está en la columna 1.
gcc / clanggcc -Wall -Wextra -std=c11 -c archivo.cerror: a label can only be part of a statement si le sigue una declaración.
Revisión manualBuscar ^\s+\w+: en el cuerpo de las funciones.

Checklist de autocontrol

Reglas relacionadas