Tipos polimórficos en C [pdf]

Una propuesta para añadir tipos polimórficos al lenguaje C, mediante nuevos constructos como `_Type` y `_Var`, ha reavivado tensiones de larga data sobre cuánto debería evolucionar C frente a ceder el paso a C++ o a lenguajes de sistemas más recientes. Quienes la apoyan sostienen que los genéricos seguros en tipos, mejores arrays y la información de tipos en tiempo de ejecución mejorarían de forma material la seguridad, la reutilización y la interoperabilidad en ámbitos como sistemas embebidos y aviación, especialmente donde los compiladores de C++ no están disponibles o no son fiables. Los críticos replican que el diseño parece ad hoc y sintácticamente feo, corre el riesgo de “engordar” C con soluciones a medias en lugar de tomar prestadas de forma limpia ideas ya probadas, y podría socavar el atractivo de C como lenguaje núcleo pequeño y predecible.

Recepción general de los tipos polimórficos en C

  • Muchos consideran que los tipos polimórficos son realmente útiles, especialmente para bibliotecas genéricas y como sustitutos más seguros de patrones con void*.
  • La propuesta se ve como “valiente”, pero también como “parcheada” y torpemente añadida sobre el sistema de tipos existente de C, en lugar de ser un diseño limpio y de primera clase.
  • A algunos les gusta que apunte más allá de las plantillas al estilo C++ hacia una tipificación polimórfica/dependiente más potente, evitando la monomorfización y la hinchazón de código.
  • Otros critican las reglas semánticas condicionales (“solo válido en algunos contextos”) porque recuerdan la complejidad de C++ y dificultan razonar sobre el código.

C frente a C++ y otros lenguajes

  • Un tema recurrente: “usa simplemente C++” para genéricos y polimorfismo frente a “C++ está inflado y es un desastre”.
  • Varios sostienen que C debería elegir solo las “buenas partes” de C++ en una forma más simple; otros creen que eso no es lo que está ocurriendo: las nuevas funciones parecen a medio comprometer y más extrañas de lo necesario.
  • Algunos han pasado explícitamente de C++ de vuelta a C, citando la complejidad y el uso indebido de funciones avanzadas de C++ en bases de código reales.
  • Alternativas discutidas: Rust (percibido como derivando hacia la inflación de características), Ada (potente pero difícil de vender), Zig/Odin/D con -betterC, y C3 (con any* y una filosofía de “no big ideas”).

Seguridad de tipos, arrays y void*

  • Debate sobre si C++ es inherentemente más seguro en tipos que C:
    • El lado pro-C++ cita genéricos con plantillas, std::array, comprobación más fuerte de tipos de punteros y static_cast.
    • El lado pro-C replica que C moderno, con estilo cuidadoso (sin arrays degradados, casts mínimos, macros para seguridad), puede alcanzar una seguridad similar.
  • Arrays multidimensionales: algunos elogian los VLA de C por ser mejores que los arrays de C++; otros los califican de riesgo de seguridad, con réplicas de que las protecciones de pila mitigan esto.
  • Las APIs basadas en void* (por ejemplo, qsort, PAM, Wayland) se citan como puntos problemáticos; los genéricos seguros en tipos se ven como una motivación clave.

Sintaxis, palabras clave y estética

  • Fuerte rechazo a la estética de _Type / _Var / _Generic; muchos señalan que las bases de código en C prefieren identificadores en minúsculas.
  • Explicación: el uso de guion bajo seguido de mayúscula está reservado para no romper código existente; más adelante podrían aparecer alias en minúsculas o palabras clave verdaderas (como _Boolbool en C23).
  • Preocupa que algunas palabras clave (como _Generic) nunca recibieron alias más agradables, lo que limita su adopción; la misma preocupación se aplica a _Type y _Var.

Casos de uso y tipado dinámico / FFI

  • Los beneficios propuestos incluyen:
    • Interfaces genéricas seguras en tipos (por ejemplo, funciones tipo qsort).
    • Construcción más sencilla de tipos y llamadas a funciones en tiempo de ejecución para interoperabilidad entre lenguajes, si _Typeof puede proporcionar descripciones de tipos en tiempo de ejecución inspeccionables.
  • Algunos cuestionan si estas necesidades justifican complicar C en lugar de elegir otro lenguaje; otros sostienen que ningún lenguaje existente iguala la combinación de simplicidad, portabilidad y control de C.