¿Por qué hay tan pocos compiladores de C?

72

C es uno de los idiomas más utilizados en el mundo. Representa una gran proporción de código existente y continúa siendo utilizado para una gran cantidad de código nuevo. Es querido por sus usuarios, está tan ampliamente adaptado que poder ejecutar C es para muchos la definición de plataforma informal, y sus admiradores lo elogian por ser un lenguaje "pequeño" con un lenguaje relativamente limpio. conjunto de características.

Entonces, ¿dónde están todos los compiladores?

En el escritorio, hay (de manera realista) dos : GCC y Clang. Pensando en ello por unos segundos probablemente recordará que Intel también existe. Hay un puñado de otros, demasiado oscuros para que la persona promedio los nombre y casi no se molestan en admitir una versión de lenguaje reciente (o, a menudo, incluso un subconjunto de lenguaje bien definido, solo "un subconjunto"). La mitad de los miembros de esta lista son notas históricas; la mayoría del resto son muy especializados y aún no implementan el lenguaje completo. Muy pocos realmente parecen ser de código abierto.

Scheme and Forth - otros lenguajes pequeños que son muy queridos por sus seguidores - probablemente tengan más compiladores que los usuarios reales. Incluso algo como SML tiene más implementaciones "serias" para elegir que C. Mientras que el anuncio de un compilador de C nuevo (sin terminar) que apunta a la verificación en realidad ve algunas respuestas bastante negativas, y implementaciones veteranas luchan por conseguir suficientes colaboradores para alcanzar incluso el C99.

¿Por qué? ¿Es tan difícil implementar C? No es C ++. ¿Los usuarios simplemente tienen una idea muy sesgada acerca de en qué grupo de complejidad se encuentra (es decir, que en realidad está más cerca de C ++ que de Scheme)?

    
pregunta 19.02.2015 - 03:26

5 respuestas

148

Hoy necesita un compilador de C real para ser un compilador de optimización , especialmente porque C ya no es un lenguaje cercano. al hardware, porque los procesadores actuales son increíblemente complejos ( off-of-order , pipelined , superscalar , con complejos cachés & TLB , por lo que necesito la programación de instrucciones de , etc ...). Los procesadores x86 de hoy no son como los procesadores i386 del siglo anterior, incluso si ambos son capaces de ejecutar el mismo código de máquina.

Pocas personas utilizan compiladores de C no optimizados como tinycc o nwcc , ya que producen un código que es varias veces más lento de lo que los compiladores de optimización pueden ofrecer.

Codificar un compilador de optimización es difícil. Tenga en cuenta que tanto GCC como Clang están optimizando alguna representación de código "independiente del idioma de origen" (Gimple para GCC, LLVM para Clang). ¡La complejidad de un buen compilador de C no está en la fase de análisis!

En particular, hacer un compilador de C ++ no es mucho más difícil que hacer un compilador de C: analizar C ++ y transformarlo en alguna representación de código interno es complejo (porque la especificación de C ++ es compleja), pero se entiende bien, pero las partes de optimización son aún más complejos (dentro de GCC: las optimizaciones de gama media, el idioma de origen y el procesador de destino son neutros, forman la mayoría del compilador, y el resto se equilibra entre las aplicaciones para varios idiomas y back-ends para varios procesadores). Por lo tanto, la mayoría de los compiladores de C que optimizan también pueden compilar algunos otros lenguajes, como C ++, Fortran, D, ... Las partes específicas de C ++ de GCC son aproximadamente el 20% del compilador ...

Además, C (o C ++) se usa tanto que las personas esperan que su código sea compilable incluso cuando no sigue exactamente los estándares oficiales, que no definen con suficiente precisión la semántica del idioma (por lo que cada compilador puede tener Su propia interpretación de ello). Busque también en el CompCert y el compilador de C probado, y el Frama -C analizador estático, que se preocupa por una semántica de C.

más formal.

Y las optimizaciones son un fenómeno long-tail : implementar algunas optimizaciones simples es fácil, pero no se lograrán. Un compilador competitivo! Debe implementar muchas optimizaciones diferentes, y organizarlas y combinarlas de manera inteligente para obtener un compilador real que sea competitivo. En otras palabras, un compilador optimizador del mundo real debe ser una pieza compleja de software. Por cierto, tanto GCC como Clang / LLVM tienen varios generadores internos de código C / C ++ especializados. Y ambas son grandes bestias (varios millones de líneas de código fuente, con una tasa de crecimiento de varios por ciento cada año) con una gran comunidad de desarrolladores (unos pocos cientos de personas, que trabajan en su mayoría a tiempo completo, o al menos a medio tiempo). / p>

Observe que hay no (a mi entender) el compilador C de múltiples subprocesos, incluso si algunas partes de un compilador podrían ejecutarse en paralelo (por ejemplo, optimización intra-procedimiento, asignación de registros, programación de instrucciones ...). Y la creación paralela con make -j no siempre es suficiente (especialmente con LTO ).

Además, es difícil obtener financiación para codificar un compilador de C desde cero, y tal esfuerzo debe durar varios años. Finalmente, la mayoría de los compiladores C o C ++ son software libre hoy en día (ya no existe un mercado para los compiladores propietarios nuevos vendidos por startups) o al menos son productos monopólicos (como Microsoft Visual C ++ ), y ser un software gratuito es casi obligatorio para los compiladores (porque necesitan contribuciones de muchas organizaciones diferentes).

Me encantaría obtener fondos para trabajar en un compilador de C desde cero como software libre, ¡pero no soy tan ingenuo como para creer que hoy es posible!

    
respondido por el Basile Starynkevitch 19.02.2015 - 07:02
69

Me gustaría refutar su suposición subyacente de que solo hay un pequeño número de implementaciones de C.

Ni siquiera sé C, no uso C, no soy miembro de la comunidad C y, sin embargo, incluso sé mucho más que los pocos compiladores que mencionaste.

En primer lugar, está el compilador que probablemente empequeñece completamente tanto a GCC como a Clang en el escritorio: Microsoft Visual C. A pesar de las incursiones que OSX y Linux han tenido en el escritorio, y la cuota de mercado que iOS y Android tienen "robado" lejos de los antiguos usuarios de escritorio tradicionales, Windows sigue siendo el sistema operativo de escritorio dominante, y la mayoría de los programas C de escritorio de Windows probablemente se compilan con las herramientas de Microsoft.

Tradicionalmente, cada proveedor de sistema operativo y cada proveedor de chips tenían sus propios compiladores. Microsoft, como proveedor de sistemas operativos, tiene Microsoft Visual C. IBM, como proveedor de sistemas operativos y proveedor de chips, tiene XLC (que es el compilador del sistema predeterminado para AIX y el compilador con el que se compilan tanto AIX como i / OS) . Intel tiene su propio compilador. Sun / Oracle tienen su propio compilador en Sun Studio.

Luego, están los proveedores de compiladores de alto rendimiento, como PathScale y The Portland Group, cuyos compiladores (y bibliotecas OpenMP) se usan para numbercrunching.

Digital Mars también sigue en el negocio. Creo que Walter Bright tiene la distinción única de ser la única persona en el planeta que logró crear un compilador de C ++ de calidad de producción (en su mayoría) por sí mismo.

Por último, pero no menos importante, tenemos todos los compiladores propietarios para microcontroladores integrados. IIRC, cada año se venden más microcontroladores que las computadoras de escritorio, móviles, servidores, estaciones de trabajo y mainframe que se han vendido en toda la historia de la computación combinada. Por lo tanto, esos son definitivamente productos de nicho de no .

Una mención honorífica va a TruffleC , un intérprete de C ( !) ejecutándose en la JVM (!) escrita utilizando el marco de intérprete de Truffle AST que es solo un 7% más lento que GCC y Clang (el que sea más rápido en cualquier punto de referencia) en el juego de referencia de lenguajes informáticos, y más rápido que ambos en microbenchmark. Usando TruffleC, el equipo de Truffle pudo obtener su versión de JRuby + Truffle para ejecutar las extensiones de Ruby C más rápido que la implementación real de C Ruby.

Por lo tanto, estas son 6 implementaciones además de las que mencionaste, las cuales puedo mencionar desde lo alto de mi cabeza, sin siquiera saber nada acerca de C.

    
respondido por el Jörg W Mittag 19.02.2015 - 07:22
8

¿Cuántos compiladores necesitas?

Si tienen diferentes conjuntos de características, creas un problema de portabilidad. Si están acostumbrados, elija el "predeterminado" (GCC, Clang o VS). Si te preocupa el último 5% de rendimiento, tienes un punto de referencia desactivado.

Si está realizando un trabajo de lenguaje de programación de forma recreativa o con fines de investigación, es probable que esté en un lenguaje más moderno. De ahí la proliferación de compiladores de juguete para Scheme y ML. Aunque parece que OCaml está recibiendo algo de tracción para usos no académicos que no sean juguetes.

Tenga en cuenta que esto varía mucho según el idioma. Java tiene esencialmente la cadena de herramientas Sun / Oracle y la GNU. Python tiene varios compiladores, ninguno de los cuales es realmente respetado en comparación con el intérprete estándar. Rust and Go tiene exactamente una implementación cada uno. C # tiene Microsoft y Mono.

    
respondido por el pjc50 19.02.2015 - 11:14
6

C / C ++ es único entre los lenguajes compilados, ya que tiene 3 implementaciones principales de una especificación común.

Siguiendo la regla de descartar cualquier cosa que no se use mucho, cualquier otro lenguaje compilado tiene 0 a 1.

Y creo que JavaScript es la única razón por la que necesitas especificar 'compilado'.

    
respondido por el soru 19.02.2015 - 14:45
5

Entonces, ¿cuál es su idioma de destino?

Los compiladores SML a menudo están dirigidos a C o algo así como LLVM (o como se ve en su enlace, la JVM o JavaScript).

Si está compilando C, no es porque vaya a la JVM. Vas a algo peor que C. Mucho peor. Y luego puedes duplicar ese infierno menor un montón de veces para todas tus plataformas de destino.

Y seguro, C no es C ++, pero yo diría que está más cerca de C ++ que de Scheme. Tiene su propio subconjunto de maldad de comportamiento indefinido (te estoy viendo el tamaño de los tipos incorporados). Y si arruinas esos detalles (o lo haces "correctamente" pero de forma inesperada) entonces tienes décadas de código existente en sistemas vitales que te dirán lo terrible que eres. Si arruinas un compilador SML, simplemente no funcionará, y alguien podría notificarlo. Algún día.

    
respondido por el Telastyn 19.02.2015 - 03:41

Lea otras preguntas en las etiquetas