Regla 0x0013h: Detector de etiquetas de salto goto no alineadas al margen izquierdo
Sintaxis y formato visual (0x00XX)
0x0013h: Detector de etiquetas de salto goto no alineadas al margen izquierdo¶
Enunciado normativo¶
Toda etiqueta de salto
gotousada 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 consecuencia | Efecto concreto |
|---|---|
| Legibilidad | Una etiqueta indentada se confunde con una llamada o etiqueta de switch. |
| Mantenibilidad | Al mover bloques, es fácil arrastrar la etiqueta y romper la convención. |
| Compilación | Una 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¶
Etiquetas de
switch:caseydefaultvan indentadas; esta regla no las alcanza.gotohacia atrás: además de la alineación, está prohibido por 0x1011h: Prohibición de saltos no estructurados goto fuera del patrón canónico de liberación de recursos.Preferencia pedagógica: si se puede evitar el
goto, mejor (0x1006h: No utilizar la instrucción goto).
Cómo detectarla¶
| Herramienta | Comando | Señal |
|---|---|---|
gaff | gaff check archivo.c | Reporta una etiqueta que no está en la columna 1. |
gcc / clang | gcc -Wall -Wextra -std=c11 -c archivo.c | error: a label can only be part of a statement si le sigue una declaración. |
| Revisión manual | — | Buscar ^\s+\w+: en el cuerpo de las funciones. |
Checklist de autocontrol¶
Toda etiqueta de
gotoestá en la columna 1.Inmediatamente después de la etiqueta hay una sentencia, no una declaración.
Usé el
gotosólo en el patrón de limpieza tolerado por 0x1011h: Prohibición de saltos no estructurados goto fuera del patrón canónico de liberación de recursos.
Reglas relacionadas¶
0x1011h: Prohibición de saltos no estructurados goto fuera del patrón canónico de liberación de recursos — único uso tolerado del
goto.0x1006h: No utilizar la instrucción goto — prohibición general del
goto.0x300Fh: Liberá la memoria en el orden inverso a su asignación — liberar recursos en orden inverso.