Regla 0x1004h: Las condiciones complejas deben simplificarse o comentarse
Estructuras de control y flujo (0x10XX)
0x1004h: Las condiciones complejas deben simplificarse o comentarse¶
Enunciado normativo¶
DEBE dividirse toda condición que combine múltiples operadores lógicos en partes más pequeñas mediante variables booleanas auxiliares con nombre significativo o funciones de validación. Cuando la división no sea posible, DEBE documentarse la intención de cada subexpresión con un comentario.
No se admite como respuesta “agregar paréntesis y seguir”: los paréntesis aclaratorios pertenecen a 0x1013h: Detector de expresiones booleanas complejas sin paréntesis aclaratorios, pero la condición sigue siendo una sola expresión sin nombre.
¿Por qué existe esta regla?¶
El problema¶
Una condición con varios && y || obliga a reconstruir la precedencia mental
y a recordar para qué servía cada término. El problema no es sintáctico —el
compilador la evalúa perfecto—, sino cognitivo: el lector no sabe qué
combinación de hechos representa la expresión.
Extraer subexpresiones a variables con nombre convierte la condición en una frase: cada variable es un hecho y la condición final los combina. Además, el nombre permite verificar por separado que cada término mide lo que dice medir.
Consecuencias de violarla¶
| Tipo de consecuencia | Efecto concreto |
|---|---|
| Bug lógico | Un operador mal combinado pasa desapercibido por la longitud de la expresión. |
| Dificultad de prueba | No se puede verificar un subconjunto de la condición de forma aislada. |
| Mantenibilidad | Cambiar un término obliga a releer toda la expresión. |
| Duplicación | La misma combinación se repite en otras ramas y se desincroniza. |
Fundamento en el estándar y en la cátedra¶
El estándar C define la precedencia de && sobre || (§6.5.13–6.5.14), pero
la cátedra adopta la legibilidad como criterio superior (0x0001h: La claridad y prolijidad son de máxima importancia). La
guía editorial pide explicar el “porqué” antes del “cómo”; una condición
auxiliar nombrada es la forma de registrar ese “porqué” en el propio código.
Alcance y excepciones¶
Aplica cuando conviven tres o más operadores lógicos, o cuando la misma combinación se repite.
Una comparación simple
a < b,x == yno requiere extracción.Dos operadores de la misma familia (
a && b && c) suelen ser legibles; la regla apunta sobre todo a la mezcla de&&y||.
Ejemplos exhaustivos¶
❌ Contraejemplo 1 — condición de autorización ilegible¶
if ((usuario_activo && tiene_permisos && !mantenimiento) || (es_admin && clave_maestra))
{
permitir();
}Por qué falla: no se distingue si un administrador necesita o no estar activo, ni si el mantenimiento lo bloquea. Cada intento de modificarla puede cambiar la lógica sin que el diff lo evidencie.
❌ Contraejemplo 2 — la misma condición repetida y divergente¶
if ((x > 0 && x < 100) || modo_prueba)
{
aceptar(x);
}
if (x > 0 && x < 100)
{
registrar(x);
}Por qué falla: la validez de x está copiada en dos lugares. Si mañana el rango
cambia, una de las dos copias queda desactualizada y el programa registra datos
que antes aceptó o al revés.
✅ Ejemplo conforme 1 — variables auxiliares con nombre¶
bool dentro_de_rango = x > 0 && x < 100;
bool acceso_concedido = usuario_activo && tiene_permisos && !mantenimiento;
bool es_administrador = es_admin && clave_maestra;
if (acceso_concedido || es_administrador)
{
permitir();
}Cada variable nombra un hecho verificable. La condición final se lee como una frase y cada término se puede probar por separado.
✅ Ejemplo conforme 2 — función de validación reutilizable¶
static bool rango_valido(int x)
{
return x > 0 && x < 100;
}El llamador queda if (rango_valido(x) || modo_prueba) y la definición del
rango vive en un único lugar, reutilizable por las dos ramas del contraejemplo
2.
⚠️ Casos límite¶
Condición con efectos secundarios: al extraerla, cuidá que las llamadas se evalúen en el mismo orden y la misma cantidad de veces; el cortocircuito cambia si se reordena.
x == 0 && y == 0: dos términos simples no necesitan auxiliares.Condición generada por macro: el nombre de la macro cumple el rol de variable auxiliar, pero debe seguir las reglas de 0x500Ah: Protección obligatoria de parámetros en macros funcionales mediante paréntesis.
Cómo detectarla¶
| Herramienta | Comando | Señal |
|---|---|---|
gaff | gaff check archivo.c | Regla 0x1004h: condición compleja. |
gcc | gcc -Wall -Wextra | No la detecta; es una regla de diseño. |
| Revisión manual | — | Tres o más operadores lógicos mezclados en un if. |
Checklist de autocontrol¶
¿La condición mezcla
&&y||? Extraje subexpresiones con nombre.¿Cada variable auxiliar tiene un nombre que describe un hecho?
¿Evité repetir la misma combinación en otra rama?
¿El orden de evaluación y los efectos secundarios se preservaron?
Reglas relacionadas¶
0x1013h: Detector de expresiones booleanas complejas sin paréntesis aclaratorios — exige paréntesis cuando se mezclan
&&y||.0x0201h: Escribí comentarios que expliquen el ‘porqué’, no el ‘qué’ — los comentarios explican el “porqué” de cada subcondición.
0x0001h: La claridad y prolijidad son de máxima importancia — la claridad es el criterio superior de la cátedra.