Regla 0x2013h: Detector de bloques else superfluos tras sentencias terminales
Funciones, contratos y modularizacion (0x20XX)
0x2013h: Detector de bloques else superfluos tras sentencias terminales¶
Enunciado normativo¶
NO DEBE conservarse el bloque
elsecuando la ramaiftermina incondicionalmente conreturn,exit,break,continueogoto. El flujo posterior DEBE desanidarse al mismo nivel delif.
¿Por qué existe esta regla?¶
El problema¶
Si la rama if siempre sale —retorna o interrumpe—, cuando el control llega a
la línea siguiente es porque la condición fue falsa. El else repite una
condición que el flujo ya garantiza y solo agrega indentación. Ese nivel de más
es la anidación en flecha que 0x2001h: Las funciones deben usar cláusulas de guarda y retornos anticipados para reducir la anidación profunda combate: desanidar deja el camino
principal al ras y hace visible que el else era ruido.
Consecuencias de violarla¶
| Tipo de consecuencia | Efecto concreto |
|---|---|
| Anidación | Cada else innecesario corre el cuerpo principal hacia la derecha. |
| Legibilidad | El lector procesa una condición que el flujo ya resolvió. |
| Mantenibilidad | Un caso nuevo pide un else if que podría ser un if plano. |
| Consistencia | Se pierde la uniformidad con 0x100Fh: Prohibición de cláusula else redundante tras sentencia de retorno anticipado y 0x2001h: Las funciones deben usar cláusulas de guarda y retornos anticipados para reducir la anidación profunda. |
Fundamento en el estándar y en la cátedra¶
C11 define la sentencia if con una cláusula else opcional (§6.8.4.1). Que
sea opcional es el punto: if (...) { return; } else { ... } equivale a
if (...) { return; } .... La cátedra pide la segunda forma porque la primera
sugiere una alternativa que la semántica ya descartó.
Alcance y excepciones¶
Cubre return, exit, break, continue y goto al final de la rama if.
No aplica si la sentencia terminal está condicionada dentro de un bloque
interno (un return que no es incondicional respecto del if externo).
Tampoco cuando ambas ramas son simétricas y breves y conservar el else mejora
la lectura; esa decisión se documenta.
Ejemplos exhaustivos¶
❌ Contraejemplo 1 — else tras retorno¶
int validar(int x)
{
if (x < 0) {
return ERROR_RANGO;
} else {
return OK;
}
}Si x < 0 ya se retornó; el else solo envuelve una línea que podría estar al ras.
❌ Contraejemplo 2 — else if encadenado innecesario¶
int clasificar(int nota)
{
if (nota >= 8) {
return APROBADO;
} else if (nota >= 4) {
return REGULAR;
} else {
return DESAPROBADO;
}
}Cada else repite que la condición anterior fue falsa; los tres if pueden ir
al mismo nivel.
✅ Ejemplo conforme 1 — Desanidado tras retorno¶
int validar(int x)
{
if (x < 0) {
return ERROR_RANGO;
}
return OK;
}El segundo retorno está al nivel del if; el lector ve dos caminos secuenciales.
✅ Ejemplo conforme 2 — Cadena plana de clasificación¶
enum estado_nota_t clasificar(int nota)
{
if (nota >= 8) {
return APROBADO;
}
if (nota >= 4) {
return REGULAR;
}
return DESAPROBADO;
}Cada condición se evalúa en secuencia y los retornos usan símbolos de dominio
(0x2007h: Los valores de retorno numéricos deben definirse como constantes de preprocesador o enums); no hay un solo else.
⚠️ Casos límite¶
Rama con
break/continue: también son terminales dentro de un lazo, así que el mismo criterio aplica.Simetría legítima: en dos ramas breves y equilibradas, conservar el
elsepuede ser más claro; la cátedra prioriza el desanidado.
Cómo detectarla¶
| Herramienta | Comando | Señal |
|---|---|---|
gaff | gaff check archivo.c | else tras una rama con return/exit/break. |
clang-tidy | clang-tidy -checks=readability-else-after-return archivo.c | Diagnóstico de else redundante. |
Checklist de autocontrol¶
¿Alguna rama
iftermina siempre enreturn,breakocontinue?¿El
elseaporta algo que el flujo no garantice?¿El estilo coincide con las guardas de 0x2001h: Las funciones deben usar cláusulas de guarda y retornos anticipados para reducir la anidación profunda?
Reglas relacionadas¶
0x2001h: Las funciones deben usar cláusulas de guarda y retornos anticipados para reducir la anidación profunda — las guardas son el mecanismo que vuelve innecesario el
else.0x100Fh: Prohibición de cláusula else redundante tras sentencia de retorno anticipado — misma prohibición formulada en el bloque de control.
0x2005h: Cada función debe tener una única responsabilidad (Principio de Responsabilidad Única) — menos anidación acompaña funciones de un solo foco.