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 0x1015h: Limitá la profundidad de anidación a tres niveles

Estructuras de control y flujo (0x10XX)

Universidad Nacional de Río Negro

0x1015h: Limitá la profundidad de anidación a tres niveles

Enunciado normativo

NO DEBE superarse una profundidad de anidación de tres niveles (una función más dos bloques de control anidados). Cuando un cuarto nivel aparece, DEBE extraerse una función, invertirse la condición o consolidarse el bloque.

¿Por qué existe esta regla?

El problema

Cada nivel de anidación agrega una condición que el lector debe tener activa en la memoria mientras analiza el cuerpo interno. Con cuatro o cinco niveles, la cláusula else de más arriba queda a decenas de líneas de distancia y se vuelve imposible saber a qué if responde cada }.

La anidación profunda también es el síntoma típico de mezclar varias responsabilidades en un mismo bloque (ver 0x2014h: Cada función debe caber en una sola idea y en 25 líneas).

Consecuencias de violarla

Tipo de consecuenciaEfecto concreto
LegibilidadEl “camino feliz” queda enterrado al final de una pirámide.
Errores lógicosUn else mal ubicado o una llave mal cerrada pasan desapercibidos.
TestingCada camino requiere preparar todo el contexto de los niveles externos.
MantenimientoAgregar una condición obliga a reindentar medio archivo.

Fundamento en la cátedra

Es la versión cuantificable de 0x2001h: Las funciones deben usar cláusulas de guarda y retornos anticipados para reducir la anidación profunda. El límite de tres niveles mantiene el cuerpo de la función dentro de una pantalla y hace visible el flujo incluso sin editor. Es además una métrica estándar de complejidad ciclomática.

Alcance y excepciones

Cuentan como niveles la función y cada if, for, while, do, switch o bloque anidado. Un switch con case que a su vez tiene un if y un for ya está en el límite. Se exceptúan tablas de inicialización anidadas (struct dentro de struct) que no representan flujo de control.

Ejemplos exhaustivos

❌ Contraejemplo 1 — Pirámide de condiciones

int procesar(int v[], int n)
{
    if (n > 0) {
        for (int i = 0; i < n; i++) {
            if (v[i] > 0) {
                if (v[i] % 2 == 0) {
                    if (v[i] < limite) {
                        acumular(v[i]);
                    }
                }
            }
        }
    }
    return total;
}

Por qué falla: cuatro niveles dentro del for; el lector debe sostener n > 0, la iteración, v[i] > 0 y la paridad para entender una sola línea. La función hace demasiado (0x2014h: Cada función debe caber en una sola idea y en 25 líneas).

❌ Contraejemplo 2 — else colgante por exceso de niveles

if (a)
    if (b)
        if (c)
            accion_a();
        else
            accion_b();

Por qué falla: sin llaves, el else se asocia al if más cercano, no al que el autor imaginó. Es el antipatrón dangling else (0x1001h), favorecido por el anidamiento profundo y la falta de llaves (0x1001h: Todas las estructuras de control deben utilizar llaves).

✅ Ejemplo conforme 1 — Guardas y extracción

static bool es_par_positivo_menor(int x, int limite)
{
    return x > 0 && x % 2 == 0 && x < limite;
}

int procesar(int v[], int n)
{
    if (n <= 0) {
        return 0;
    }

    for (int i = 0; i < n; i++) {
        if (es_par_positivo_menor(v[i], limite)) {
            acumular(v[i]);
        }
    }

    return total;
}

La condición múltiple se volvió una función con nombre; el lazo queda en dos niveles y el camino de error (n <= 0) se atiende primero.

✅ Ejemplo conforme 2 — Invertir la condición

for (int i = 0; i < n; i++) {
    if (v[i] <= 0) {
        continue;    /* descarta temprano */
    }
    procesar_positivo(v[i]);
}

En lugar de anidar todo bajo if (v[i] > 0), se descarta el caso no deseado y el resto queda al primer nivel. (Usar continue sólo donde la cátedra lo permita; ver 0x1002h: Restringí el uso de break y continue; preferí lazos con bandera de control.)

⚠️ Casos límite

Cómo detectarla

HerramientaComandoSeñal
Revisión manualCuatro { consecutivos antes de una sentencia.
gigergiger <archivo.c>Métricas de complejidad por función.
gccgcc -Wall -Wextra-Wdangling-else advierte el else ambiguo.

Checklist de autocontrol

Reglas relacionadas