El lenguaje C, aunque estandarizado, presenta divergencias significativas entre su especificación teórica y las implementaciones prácticas de compiladores como GCC y Clang, así como de librerías como glibc y musl. Esta discrepancia afecta la portabilidad y la conformidad del código, especialmente en áreas críticas como la aritmética de punto flotante y la gestión de memoria.
Una de las principales incompatibilidades es el uso de la directiva asm. Aunque el estándar C permite 'asm' como un identificador no reservado, GCC y Clang lo tratan como una extensión por defecto, lo que impide la compilación de código estrictamente conforme al estándar sin configurar explícitamente el modo de compilación. Además, el estándar define la macro FLT_ROUNDS para controlar el redondeo de operaciones flotantes, pero GCC la fija siempre a 1, ignorando las llamadas a fesetround, mientras que Clang ofrece una función interna para gestionar esto.
Otro punto de fricción son los pragmas estándar de C99 y C23, diseñados para controlar el comportamiento de los errores de punto flotante. A pesar de su inclusión en el estándar, GCC no los soporta de forma nativa, tratándolos como operaciones vacías, mientras que Clang solo soporta los de C99 y no los de C23. Esto limita la capacidad de los programadores para aplicar estas configuraciones a funciones específicas.
Finalmente, se identifican errores en la implementación de POSIX. Por ejemplo, la función initstate en glibc no devuelve NULL en caso de error, a diferencia de lo que exige el estándar POSIX. Asimismo, la definición de va_start en musl es incorrecta para el estándar C23, impidiendo el uso de la forma de un argumento. Estas diferencias requieren a los desarrolladores verificar la conformidad de sus código y utilizar configuraciones específicas para cada compilador y librería.
