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 0x1002h: Restringí el uso de break y continue; preferí lazos con bandera de control

Estructuras de control y flujo (0x10XX)

Universidad Nacional de Río Negro

0x1002h: Restringí el uso de break y continue; preferí lazos con bandera de control

Enunciado normativo

NO DEBE usarse continue para controlar un lazo, en ningún caso. El uso de break se admite excepcionalmente para salir de forma anticipada de un lazo cuando simplifica la lógica, pero se DEBE preferir una bandera booleana de control en la condición del lazo.

El break obligatorio del switch no está alcanzado por esta regla (ver 0x1008h: Toda instrucción switch debe incluir un caso default).

¿Por qué existe esta regla?

El problema

continue corta la iteración en un punto intermedio y salta al incremento. El lector que sigue el cuerpo de arriba hacia abajo debe recordar que existe una puerta de salida lateral; cualquier sentencia colocada después del continue puede no ejecutarse. break, cuando se usa como único mecanismo de corte, convierte la condición del lazo en una mentira: el encabezado dice i < n, pero el lazo en realidad se detiene por otra causa. La bandera de control traslada esa causa a la condición, donde el lector la ve junto con la cota.

Consecuencias de violarla

Tipo de consecuenciaEfecto concreto
Bug silenciosoCódigo después del continue no se ejecuta y la omisión pasa desapercibida.
MantenibilidadAgregar una sentencia al final del cuerpo puede quedar tras el continue.
TestingLos caminos de corte quedan ocultos y no se cubren con casos de prueba.

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

ISO/IEC 9899:2011 §6.8.6.2 define continue como un salto al final del cuerpo, y §6.8.6.3 al break como salida inmediata. Ambos son válidos para el compilador, pero la cátedra prioriza el flujo estructurado de salida única de Dijkstra. Se admite break sólo cuando elimina un anidamiento o banderas redundantes, y se prohíbe continue por su salto lateral.

Alcance y excepciones

Ejemplos exhaustivos

❌ Contraejemplo 1 — continue que oculta una validación

for (int i = 0; i < n; i++)
{
    if (valores[i] < 0)
    {
        continue;
    }
    suma += valores[i];
}

Por qué falla: cualquier estadística que se agregue al final del cuerpo queda después del continue y omitirá los negativos sin que nada lo recuerde. La condición del for no anuncia el filtro.

❌ Contraejemplo 2 — break como única salida de un while (1)

while (1)
{
    int c = leer_sensor();
    if (c == CODIGO_CORTE)
    {
        break;
    }
    procesar(c);
}

Por qué falla: while (1) declara un lazo que nunca termina. La causa real de corte está enterrada en el cuerpo; el lector no puede saber cuándo sale mirando el encabezado. Si aparece un segundo motivo de corte, se suma otro break.

✅ Ejemplo conforme 1 — bandera de control

bool terminar = false;
while (!terminar)
{
    int c = leer_sensor();
    if (c == CODIGO_CORTE)
    {
        terminar = true;
    }
    else
    {
        procesar(c);
    }
}

La condición !terminar expone la causa de corte y la salida es única. Sumar otro motivo se resuelve activando la misma bandera.

✅ Ejemplo conforme 2 — corte expuesto en la condición

bool encontrado = false;
for (size_t i = 0; i < n && !encontrado; i++)
{
    if (valores[i] == buscado)
    {
        encontrado = true;
    }
}

Acá el corte se expone en la condición y el break ni siquiera hace falta. Si se optara por un break tras encontrado = true, seguiría siendo una salida anticipada justificada: se encontró el resultado y no hay trabajo pendiente.

⚠️ Casos límite

Cómo detectarla

HerramientaComandoSeñal
gaffgaff check archivo.cRegla 0x1002h: uso de break/continue.
Búsquedagrep -n "continue" archivo.cToda aparición es una violación.
Revisión manualwhile (1) con break como única salida.

Checklist de autocontrol

Reglas relacionadas

Antipatrón: Bucle infinito con salida condicionada exclusivamente por exit()

Síntoma en el código del estudiante

Un lazo while (1) termina el programa entero mediante exit() en lugar de salir de forma estructurada:

while (1)
{
    if (fin)
    {
        exit(0);
    }
    procesar();
}

Diagnóstico

Mecanismo del defecto

exit() termina el proceso completo (ISO/IEC 9899:2011 §7.22.4.4): abandona el lazo, la función y toda la cadena de llamadas. El control nunca vuelve al llamador, con lo que se omite cualquier limpieza pendiente definida después del lazo (liberar memoria, cerrar archivos, restaurar estado).

Consecuencia observable

El programa termina “correctamente” para el usuario, pero deja recursos sin liberar y evita que el código de limpieza se ejecute. En pruebas unitarias, la función no puede retornar y la prueba muere con el proceso; no se puede distinguir el éxito del fallo ni continuar con el siguiente caso.

Fundamento en el estándar C11

ISO/IEC 9899:2011 §7.22.4.4 define exit como terminación del programa que registra las funciones de atexit y cierra los flujos, pero no ejecuta el código de limpieza local. La cátedra exige que el corte se exprese en la estructura del lazo (regla 0x1002h): una bandera de control o, si el propósito es salir de la función, un return.

Corrección idiomática

❌ Código con el antipatrón
while (1)
{
    if (fin)
    {
        exit(0);
    }
    procesar();
}
✅ Código refactorizado
bool terminar = false;
while (!terminar)
{
    if (fin)
    {
        terminar = true;
    }
    else
    {
        procesar();
    }
}

La bandera expone la condición de corte y el lazo sale por su encabezado. Si el corte debe abandonar la función, se usa return y el llamador retoma el control.

Errores típicos al compilar o ejecutar

No hay error de compilación.

En ejecución, la memoria asignada en procesar() no se libera; un
detector como valgrind o -fsanitize=address reporta:
ERROR: LeakSanitizer: detected memory leaks
directly lost: ... bytes in ... blocks

En una suite de pruebas, la prueba que invoca esta función termina
el proceso y las pruebas siguientes no se ejecutan.

Checklist de verificación

Reglas relacionadas