Regla 0x1008h: Toda instrucción switch debe incluir un caso default
Estructuras de control y flujo (0x10XX)
0x1008h: Toda instrucción switch debe incluir un caso default¶
Enunciado normativo¶
DEBE finalizar todo
switchcon un bloquedefault, aunque el autor considere que ya cubrió todos los valores posibles. Si uncaseomite elbreakde forma intencional para caer al siguiente, esa intención DEBE documentarse con un comentario// fallthrough.
¿Por qué existe esta regla?¶
El problema¶
Un switch sin default deja en silencio los valores no contemplados: el
programa simplemente continúa después del bloque, con el estado que haya
quedado. Ese camino no escrito es el que aparece cuando un dato llega corrupto
o cuando se agrega un valor nuevo a un enum y se olvida actualizar el
switch.
El default convierte lo desconocido en una decisión explícita: error,
mensaje, valor por defecto o assert. El programa deja de tener caminos
implícitos.
Consecuencias de violarla¶
| Tipo de consecuencia | Efecto concreto |
|---|---|
| Bug silencioso | Un valor no previsto se procesa como si nada hubiera pasado. |
| Mantenibilidad | Agregar una constante a un enum no obliga a revisar el switch. |
Fundamento en el estándar y en la cátedra¶
ISO/IEC 9899:2011 §6.8.4.2 define el switch y las etiquetas case y
default. El default es opcional para el estándar, pero la cátedra lo exige
como regla de robustez; se apoya en 0x300Dh: Utilizá enum en lugar de ‘números mágicos’ para conjuntos de estados y valores constantes (usar enum en lugar de
números mágicos) para que los valores sean conocidos y finitos.
Alcance y excepciones¶
Aplica a todo
switch, incluido el que hoy cubre todos los valores de unenum.Excepción documentada: un
casepuede caer intencionalmente al siguiente si y solo si lleva el comentario// fallthrough.
Ejemplos exhaustivos¶
❌ Contraejemplo 1 — switch sin default¶
switch (comando)
{
case CMD_INICIAR:
iniciar();
break;
case CMD_DETENER:
detener();
break;
}Por qué falla: un comando distinto de los dos contemplados no produce error ni
registro; el programa sigue como si el comando no hubiera existido. El olvido es
invisible.
❌ Contraejemplo 2 — fallthrough no documentado¶
switch (opcion)
{
case 1:
aplicar_descuento();
case 2:
emitir_factura();
break;
default:
reportar_opcion_invalida();
break;
}Por qué falla: quien lee el case 1 no sabe si el autor olvidó el break o
quiso aplicar descuento y además facturar. El comportamiento es el mismo, la
intención es ilegible.
✅ Ejemplo conforme 1 — default explícito¶
switch (comando)
{
case CMD_INICIAR:
iniciar();
break;
case CMD_DETENER:
detener();
break;
default:
reportar_comando_desconocido(comando);
break;
}Todo valor no previsto se diagnostica; el break final del default cierra el
bloque de forma uniforme.
✅ Ejemplo conforme 2 — fallthrough documentado¶
switch (opcion)
{
case 1:
aplicar_descuento();
// fallthrough: el descuento siempre precede a la factura
case 2:
emitir_factura();
break;
default:
reportar_opcion_invalida();
break;
}El comentario declara que caer al case 2 es intencional; el lector deja de
sospechar un olvido.
⚠️ Casos límite¶
Un default inalcanzable o vacío debe llevar un comentario que lo justifique;
en un switch sobre char también cubre '\0' y los caracteres no listados.
Cómo detectarla¶
| Herramienta | Comando | Señal |
|---|---|---|
gaff | gaff check archivo.c | Regla 0x1008h: switch sin default. |
gcc | gcc -Wall -Wextra -Wswitch-default | warning: switch statement has no default case. |
clang | clang -Wall -Wextra -Wimplicit-fallthrough | warning: unannotated fall-through. |
Checklist de autocontrol¶
¿Todos los
switchtienendefault?¿El
defaulthace algo o tiene un comentario que lo justifica?¿Cada
casetermina enbreak,returno// fallthrough?
Reglas relacionadas¶
0x1002h: Restringí el uso de break y continue; preferí lazos con bandera de control — el
breakde cadacasees obligatorio salvo fallthrough documentado.0x300Dh: Utilizá enum en lugar de ‘números mágicos’ para conjuntos de estados y valores constantes — usar
enumpara que los valores delswitchsean explícitos.0x1008h — caso de
switchsinbreakcon fallthrough no intencional.
Antipatrón: Caso de switch sin break (Fallthrough no intencional)¶
Síntoma en el código del estudiante¶
Un case termina sin break y la ejecución “cae” al case siguiente,
acumulando el trabajo de ambos:
switch (op)
{
case 1:
hacer_1();
case 2:
hacer_2();
break;
}hacer_1() se ejecuta y luego, sin pausa, hacer_2().
Diagnóstico¶
Mecanismo del defecto¶
El switch en C salta a la etiqueta case elegida y continúa ejecutando
hasta encontrar un break o el final del bloque (ISO/IEC 9899:2011 §6.8.4.2).
El break es la única interrupción; sin él, el flujo atraviesa las etiquetas
siguientes.
Consecuencia observable¶
La rama case 1 hace también el trabajo de case 2. El error no se ve en el
encabezado y suele descubrirse tarde como “efectos duplicados” o “acciones de
más”. Si se reordenan los case, el resultado cambia sin tocar el cuerpo.
Fundamento en el estándar C11¶
ISO/IEC 9899:2011 §6.8.4.2 describe el switch como un salto a la etiqueta y
la ejecución secuencial posterior. El fallthrough es legal; la cátedra exige
que, cuando sea deliberado, se documente con un comentario // fallthrough
(regla 0x1008h). El antipatrón es el fallthrough no intencional.
Corrección idiomática¶
❌ Código con el antipatrón¶
switch (op)
{
case 1:
hacer_1();
case 2:
hacer_2();
break;
}✅ Código refactorizado¶
switch (op)
{
case 1:
hacer_1();
break;
case 2:
hacer_2();
break;
default:
reportar_opcion(op);
break;
}Cada case cierra con break y el default cubre los valores no listados. Si
el fallthrough fuera intencional, se escribiría // fallthrough en lugar de
break.
Errores típicos al compilar o ejecutar¶
Con -Wimplicit-fallthrough (Clang / GCC 7+):
warning: unannotated fall-through between switch labels [-Wimplicit-fallthrough]
En ejecución, con op == 1 el programa llama a hacer_1() y a hacer_2();
el resultado parece un error de lógica sin causa visible.Checklist de verificación¶
¿Cada
casetermina enbreak,returno comentario// fallthrough?¿El
switchincluye undefault?¿Reordenar los
casecambiaría el comportamiento? Debería no hacerlo.¿Compilé con
-Wimplicit-fallthrough?
Reglas relacionadas¶
0x1008h: Toda instrucción switch debe incluir un caso default — todo
switchdebe tenerdefaulty documentar el fallthrough.0x1002h: Restringí el uso de break y continue; preferí lazos con bandera de control — el
breakde cierre de cadacasees obligatorio.0x100Bh: No utilices comparaciones en estilo Yoda (‘CONST == variable’) — regla asociada a este antipatrón.