Por qué no debes desactivar las aserciones en producción

Fuentes: You Must Fix Your Asserts
Imagen generada por IA con el prompt: Code editor screen with a highlighted assert line and a red warning symbol, dark technical minimal style, no real faces or brand logos
Imagen generada con IA

Este artículo técnico sostiene que desactivar las aserciones en producción es una práctica «irremediablemente mala», y toma como referencia principal el comportamiento de std.debug.assert en Zig, aunque su razonamiento se aplica a la ingeniería de software en general.

¿Qué es una aserción? Es una línea de código que introduce un hecho en el programa, como «este argumento nunca puede ser nulo» o «este entero nunca será par». Si el sistema de tipos del lenguaje puede imponer la restricción, conviene usarla; si no, las aserciones documentan precondiciones, poscondiciones e invariantes. El texto cita a otro autor que afirma que «una aserción vale por mil pruebas unitarias», y mucho más si se combina con fuzzing.

En Zig, las aserciones se construyen sobre la palabra clave unreachable, que marca rutas de código inválidas. La función std.debug.assert se reduce a if (!ok) unreachable; y, a diferencia de la macro assert de C/C++, es una función normal: sus argumentos siempre se evalúan antes de la llamada, por lo que admite expresiones con efectos secundarios sin riesgo. Esto rompe la regla clásica de C/C++ de no poner efectos colaterales dentro de assert, pero a cambio elimina el comportamiento de «comentar todo al desactivar las aserciones».

Zig ofrece varios modos de compilación: Debug, ReleaseSafe, ReleaseFast y ReleaseSmall, con la particularidad de que pueden combinarse por dependencia e incluso por bloque mediante @setRuntimeSafety. En modos comprobados, una aserción fallida provoca un panic; en modos no comprobados, se produce «comportamiento ilegal no verificado» (UIB): el programa puede hacer cualquier cosa, lo que permite optimizaciones agresivas que eliminan ramas y comparaciones. El autor recuerda que los videojuegos y otras aplicaciones de tiempo real dependen masivamente de estas optimizaciones.

Las tres opciones con las aserciones son: mantenerlas como comprobaciones en tiempo de ejecución que hacen panic al fallar; usarlas para optimizaciones asumiendo el riesgo de UIB si la premisa resulta falsa; o desactivarlas por completo. Esta tercera vía, disponible en C/C++ pero no de fábrica en Zig, es la criticada: si una condición «imposible» ocurre, el programa sigue ejecutándose bajo suposiciones incorrectas, una forma de malfuncionamiento tan peligrosa como el UIB. La conclusión es clara: conviene abandonar el hábito heredado de los macros de C y mantener las aserciones activas incluso en producción.