El estándar C se libera de 45 'demonios' en su próximo borrador
El borrador C2y del estándar C eliminó 45 de los 100 comportamientos indefinidos que el lenguaje arrastraba desde C89. Martin Uecker, miembro del comité ISO/IEC WG14 que estandariza C, presentó este balance en Kernel Recipes 2026 junto con un mapa de herramientas que tu equipo puede activar hoy para protegerse de los 55 casos que quedan.
C lleva más de 50 años moviendo el mundo. Corre el kernel de tu sistema operativo, tu base de datos, el firmware del freno de tu coche y el termostato inteligente que compraste el mes pasado. Casi cualquier dispositivo enLATAM tech —desde un PoS hasta un dispositivo médico certificado— lleva C en alguna capa de su stack.
Por qué C sigue importando en 2026
Uecker abrió su charla con una pregunta directa: ¿por qué molestarse con C en 2026? Su respuesta fue concreta: C es portable, estable a largo plazo, compila rápido y produce binarios rápidos. "Lo que ves es lo que obtienes": es fácil mirar código C y entender qué va a hacer la computadora. C tiene un ecosistema de herramientas maduro y se hace a un lado cuando hace falta. Pero carga con un lastre histórico: el comportamiento indefinido.
¿Y esto cómo se aplica en tu negocio?
En CAR, dueños de empresa de Latinoamérica y España usan la tecnología para ser más rentables. Empiezas con una ruta de 7 días y terminas con un sistema funcionando en tu negocio.
👥 Probar 7 días¿Qué es el comportamiento indefinido y por qué es un problema?
El estándar C89 tuvo que lidiar con hardware muy diverso: máquinas con representación de enteros en signo-magnitud o complemento a uno, memoria segmentada, punteros exóticos y hasta bytes de 9 bits en algunas máquinas Honeywell. Para escribir un estándar portable, el comité definió la semántica en términos de una máquina abstracta: los programas deben comportarse como si se ejecutaran en esa máquina, no en el hardware real.
El problema aparece cuando un programa hace algo no portable o no definido en el estándar. C89 lo llama "comportamiento indefinido" y dice que "no impone ningún requisito" sobre la implementación. Esto existe por buenas razones: permite extensiones del compilador, soporte para mecanismos de seguridad del hardware y optimizaciones agresivas.
El problema real, según Uecker, es que el estándar permite al compilador hacer cualquier cosa ante un comportamiento indefinido. La comunidad loresume como "demonios nasales": si tu programa tiene cualquier comportamiento indefinido, un compilador puede interpretarlo como que el programa entero no tiene semántica esperada. C++23 va más allá y dice explícitamente que no impone ningún requisito para estos programas.
El caso clásico, división por cero:
extern int x;
int f(int a, int b) {
x = b ? 42 : 43;
return a/b;
}
Si b es cero, return a/b es comportamiento indefinido. Algunos compiladores eliminan la comprobación completa y solo ejecutan x = 42, asumiendo que el caso b = 0 no importa. Esto no es teoría: ocurre en compiladores reales.
El "viaje en el tiempo" que C23 prohíbe
Otro bug famoso: el compilador mueve operaciones hacia atrás en el tiempo, optimizando código que no debería. Considera este caso con volatile:
volatile int x;
int foo(int a, int b, bool store_to_x) {
if (!store_to_x)
return a/b;
x = b;
return a/b;
}
¿Puede el compilador mover la división antes de la asignación a x? Antes de C23, sí: si b = 0 no tiene semántica, no hay cambio en el comportamiento observable. El estándar C23 introdujo una estipulación de "no viaje en el tiempo" para prohibirlo. En C++, en cambio, el programador tiene que insertar explícitamente una llamada a std::observable_checkpoint().
C2y: 45 demonios menos y la estrategia del comité
El comité de C corre tres grupos de estudio dedicados específicamente al modelo de objetos en memoria, seguridad de memoria y comportamiento indefinido. ¿Cuántos comportamientos indefinidos hay? Alrededor de 100 instancias en el estándar C, según Uecker. El borrador en curso de C2y ya eliminó 45.
La situación está mejorando, pero no es trivial. Los desacuerdos entre implementadores de compiladores persisten incluso cuando el estándar es claro: la lectura de variables no inicializadas y la comparación de igualdad de punteros son casos donde tanto Clang como GCC han compilado mal código que el estándar define con precisión.
¿Qué se puede hacer HOY para atrapar comportamiento indefinido?
Uecker describió un ecosistema de herramientas cada vez más rico:
- Warnings del compilador: GCC y Clang han mejorado sus avisos para overflow de enteros y posibles casos de use-after-free.
- Analizadores estáticos: disponibles como herramientas independientes o integrados en compiladores. GCC ya advierte de varias situaciones de buffer overflow, por ejemplo.
- Sanitizers: insertan comprobaciones en tiempo de ejecución. Pueden atrapar mucho comportamiento indefinido y, en modo trapping, usarse para hardening.
- Herramientas basadas en LLM: una categoría nueva que el comité sigue con atención.
- Verificación formal: la más completa, pero la más costosa.
¿Se puede llegar a seguridad de memoria total en C?
Uecker descompuso la seguridad de memoria en tres problemas:
- Seguridad de tipos: C tiene un sistema de tipos fuerte; las uniones sin etiqueta pueden crear confusión de tipos, pero el compilador puede reforzar tipos con anotaciones. Diagnósticos nuevos detectan casts inseguros desde
void. - Seguridad espacial (bounds checking): parcialmente resuelta; los compiladores ya hacen comprobación de límites en muchos casos. El atributo
counted_bypermite comprobación en miembros de array flexibles. - Seguridad temporal (evitar use-after-free): el punto más débil de C, donde Rust tiene una ventaja clara. Aún así, arquitecturas como CHERI ayudan, y Fil-C puede encontrar muchos bugs de seguridad temporal.
¿Se puede llegar a seguridad total? Uecker fue honesto: resolverlo por completo requerirá comprobaciones costosas en tiempo de ejecución o verificación formal. En el futuro cercano, los mejores resultados vendrán de combinar lenguaje restringido + verificación formal.
¿Qué significa esto para tu startup?
Aunque no escribas C a diario, tu stack probablemente depende de C en alguna capa: el kernel, una biblioteca de procesamiento de imágenes, un SDK de hardware o un firmware embebido. Las vulnerabilidades de memoria en C siguen siendo una de las fuentes más comunes de CVE en software de producción. Esto importa especialmente si tu startup trabaja en:
- Fintech o pagos: cualquier PoS, terminal o SDK de pagos tiene componentes en C; una vulnerabilidad de memoria es un riesgo PCI-DSS.
- IoT y dispositivos conectados: la memoria segura no es opcional cuando el dispositivo vive en campo sin posibilidad de parche frecuente.
- Healthtech y dispositivos médicos: el estándar IEC 62304 y las certificaciones regulatorias europeas piden cada vez más trazabilidad de seguridad en el código de soporte vital.
- Automotriz y movilidad: cualquier producto que toque CAN bus o ADAS vive en C con memoria compartida y restricciones de tiempo real.
Tres acciones concretas que puedes tomar esta semana:
- Activa sanitizers en CI/CD (ASan, UBSan, MSan). Si mantienes una dependencia en C, añade
-fsanitize=address,undefineda tu pipeline. Encontrarás bugs que llevan años escondidos. - Configura los warnings de tu compilador al máximo (
-Wall -Wextra -Wpedanticen GCC/Clang) y trata cada warning como error en código nuevo. C23 y C2y están reduciendo los casos de UB; aprovéchalos. - Audita el código C crítico con un analizador estático (Coverity, CodeQL o el propio
-fanalyzerde GCC). Para startups hispanohablantes hay versiones open source suficientes para empezar esta semana.
El estándar C sigue vivo
C23 ya eliminó las definiciones de funciones estilo K&R, el soporte para máquinas de signo-magnitud y complemento a uno, y los trígrafos. Añadió tipos de enteros con precisión de bit, operaciones de enteros con comprobación y más. C2y irá más lejos: case ranges, named for loops, la macro _Countof() para determinar longitudes de array, y mucha más "eliminación de demonios". Uecker concluyó que C sigue siendo un lenguaje vivo y sigue mejorando. No logrará seguridad de memoria completa en C, pero es una posibilidad futura que se volverá más práctica con el tiempo.
Para los founders hispanohablantes que construyen sobre C —directa o indirectamente— la conclusión operativa es: el comité está haciendo el trabajo difícil en el estándar, pero las herramientas para proteger tu código ya están disponibles ahora. No esperes a C2y: enciende los sanitizers esta semana.
Fuentes
- Reducing undefined behavior in the C language — LWN.net
- A History of C Standardization — Robert C. Seacord
¿Y esto cómo se aplica en tu negocio?
En CAR, dueños de empresa de Latinoamérica y España usan la tecnología para ser más rentables. Empiezas con una ruta de 7 días y terminas con un sistema funcionando en tu negocio.
👥 Probar 7 días













