Por que existem tão poucos compiladores C?


72

C é uma das línguas mais usadas no mundo. É responsável por uma grande proporção do código existente e continua a ser usado por uma grande quantidade de novos códigos. É amado por seus usuários, é tão amplamente portado que ser capaz de executar C é, para muitos, a definição informal de plataforma , e é elogiado por seus fãs por ser uma linguagem "pequena" com um conjunto relativamente limpo de recursos.

Então, onde estão todos os compiladores?

Na área de trabalho, existem (realisticamente) dois : GCC e Clang. Pensando nisso por alguns segundos, você provavelmente lembrará que a Intel também existe. Existem muitos outros, muito obscuros para o nome de uma pessoa comum e quase universalmente não se preocupando em oferecer suporte a uma versão recente do idioma (ou geralmente até um subconjunto de idiomas bem definido, apenas "um subconjunto"). Metade dos membros desta lista são notas de rodapé históricas; o restante é muito especializado e ainda não implementa a linguagem completa. Muito poucos realmente parecem ser de código aberto.

Scheme e Forth - outros pequenos idiomas que são amados por seus fãs - provavelmente têm mais compiladores do que usuários reais. Até mesmo algo como SML tem implementações mais "sérias" para escolher do que C. Considerando que o anúncio de um novo compilador C (inacabado) que visa a verificação realmente vê algumas respostas bastante negativas, e as implementações veteranas lutam para conseguir colaboradores suficientes para alcançar os C99

Por quê? A implementação de C é tão difícil? Não é C ++. Os usuários simplesmente têm uma ideia muito distorcida sobre em qual grupo de complexidade ele se enquadra (isto é, na verdade, é mais próximo do C ++ do que do Scheme)?


61
O MSVC ainda conta, pelo menos como um compilador C89. Provavelmente mais popular que a Intel.
Rufflewind

22
A Wikipedia lista alguns compiladores C. Eles se tornam muito comuns quando você se encontra no reino incorporado.

113
Quantos compiladores você precisa para compilar seu código C?
19715 Bryan Chen

76
A questão é baseada em uma premissa falsa. Analog Devices, armcc, o compilador C de Bruce, o compilador Bare-C Cross, o compilador Borland, o compilador clang, o compilador Cosmic C, o compilador CodeWarrior, o compilador dokto, o compilador Ericsson, e eu nem estou fora do primeiras cinco letras do alfabeto ainda. Existe um número incrivelmente grande de compiladores C. A questão é "por que existem tão poucos compiladores C, se não contamos essas dezenas como compiladores C reais?" Você definiu a grande maioria dos compiladores C como não interessantes, e é por isso que não há muitos deles.
Eric Lippert

19
As perguntas "Por que" são más perguntas para este site na melhor das hipóteses e "por que não?" perguntas são piores. Se eu fosse encontrá-lo em uma festa e perguntasse "então, por que você não pilota veleiros?" Acho que você acharia uma pergunta estranha. Você não precisa fornecer uma justificativa para NÃO se envolver em um hobby tecnicamente difícil, fisicamente arriscado e muito caro. Escrever qualquer software não trivial é caro, difícil e arriscado e, portanto, requer um enorme motivador. Uma pergunta melhor seria "por que existem tantos compiladores C?" É surpreendente que haja mais de um.
Eric Lippert

Respostas:


153

Hoje, você precisa de um compilador C real para ser um otimizador , principalmente porque C não é mais uma linguagem próxima ao hardware, porque os processadores atuais são incrivelmente complexos ( fora de ordem , em pipeline , superescalar , com caches complexos e TLB , portanto, necessitando de agendamento de instruções , etc ...). Os processadores x86 de hoje não são como os processadores i386 do século anterior, mesmo que ambos possam executar o mesmo código de máquina. Veja que o documento C não é um idioma de baixo nível (Seu computador não é um PDP-11 rápido) de David Chisnall.

Poucas pessoas estão usando compiladores C ingênuos e não otimizadores, como tinycc ou nwcc , pois eles produzem código que é várias vezes mais lento do que o que os compiladores otimizadores podem oferecer.

Codificar um compilador otimizador é difícil. Observe que o GCC e o Clang estão otimizando alguma representação de código "neutra no idioma de origem" (Gimple for GCC, LLVM for Clang). A complexidade de um bom compilador C não está na fase de análise!

Em particular, criar um compilador C ++ não é muito mais difícil do que criar um compilador C: analisar o C ++ e transformá-lo em alguma representação de código interno é complexo (porque a especificação do C ++ é complexa), mas é bem compreendido, mas as partes de otimização são ainda mais complexo (dentro do GCC: as otimizações de ponto intermediário, idioma de origem e processador de destino neutros, formam a maioria do compilador, com o restante sendo equilibrado entre front-ends para vários idiomas e back-ends para vários processadores). Portanto, a maioria dos compiladores C otimizadores também é capaz de compilar algumas outras linguagens, como C ++, Fortran, D, ... As partes específicas de C ++ do GCC são cerca de 20% do compilador ...

Além disso, C (ou C ++) é tão amplamente usado que as pessoas esperam que seu código seja compilável, mesmo quando ele não segue exatamente os padrões oficiais, que não definem com precisão a semântica da linguagem (para que cada compilador possa ter sua própria interpretação). ). Veja também o compilador C comprovado pelo CompCert e o analisador estático Frama-C , que se preocupam com a semântica mais formal de C.

E as otimizações são um fenômeno de cauda longa : implementar algumas otimizações simples é fácil, mas elas não tornarão um compilador competitivo! Você precisa implementar muitas otimizações diferentes, organizar e combiná-las de maneira inteligente, para obter um compilador do mundo real que seja competitivo. Em outras palavras, um compilador de otimização do mundo real precisa ser um software complexo. BTW, o GCC e o Clang / LLVM têm vários geradores de código C / C ++ especializados internos. E ambos são grandes animais (vários milhões de linhas de código-fonte, com uma taxa de crescimento de vários por cento ao ano) com uma grande comunidade de desenvolvedores (algumas centenas de pessoas, trabalhando principalmente em período integral ou pelo menos meio período).

Observe que não existe (até onde sei) compilador C multithread, mesmo que algumas partes de um compilador possam ser executadas em paralelo (por exemplo, otimização intra-processual, alocação de registro, programação de instruções ...). E a construção paralela com make -jnem sempre é suficiente (especialmente com LTO ).

Além disso, é difícil obter recursos para codificar um compilador C do zero, e esse esforço precisa durar vários anos. Finalmente, a maioria dos compiladores C ou C ++ é software livre hoje (não há mais mercado para novos compiladores proprietários vendidos por startups) ou pelo menos são mercadorias monopolistas (como o Microsoft Visual C ++ ), e ser um software livre é quase necessário para compiladores ( porque precisam de contribuições de muitas organizações diferentes).

Eu ficaria muito satisfeito em conseguir financiamento para trabalhar em um compilador C do zero como software livre, mas não sou ingênuo o suficiente para acreditar que isso é possível hoje!


14
(there is no more a market for proprietary compilersDiga isso para a equipe Visual Studio ...
Mason Wheeler

18
A Microsoft tem um monopólio. Eu quis dizer que pequenas empresas que desenvolvem novos compiladores C não venderão muitos deles. Você pode nomear um concorrente proprietário recente da MSVC?
Basile Starynkevitch

12
Existem muitos compiladores proprietários no mundo da HPC. PGCC, NAG e ICC são os mais amplamente utilizados.
Davidmh

37
@MasonWheeler: VS é distribuído gratuitamente hoje em dia (como na cerveja). As versões não livres adicionam ferramentas, mas o compilador C no VS2013 é o mesmo em todas as versões. Simplesmente não há mercado, nem mesmo para eles.
MSalters

3
Mas o GCC e o LLVM estão operando em representações muito mais baixas e otimizam o código C ++ & C (& Ada & Fortran, para GCC). Eu diria, ao contrário, que o C ++ requer mais otimização (principalmente ao compilar código usando seu STL) do que o C!
Basile Starynkevitch

70

Gostaria de contestar sua suposição subjacente de que há apenas um pequeno número de implementações em C.

Eu nem conheço C, não uso C, não sou membro da comunidade C e, no entanto, conheço muito mais do que os poucos compiladores que você mencionou.

Em primeiro lugar, existe o compilador que provavelmente supera completamente o GCC e o Clang na área de trabalho: Microsoft Visual C. Apesar das incursões que o OSX e o Linux têm feito na área de trabalho, e a participação no mercado que iOS e Android "roubaram" longe dos antigos usuários de desktop tradicionais, o Windows ainda é o sistema operacional dominante na área de trabalho, e a maioria dos programas de desktop C do Windows provavelmente são compilados usando as ferramentas da Microsoft.

Tradicionalmente, todo fornecedor de SO e todo fornecedor de chips tinham seus próprios compiladores. A Microsoft, como fornecedor de SO, possui o Microsoft Visual C. A IBM, como fornecedor de SO e de chip, possui XLC (que é o compilador de sistema padrão para AIX e o compilador com o qual o AIX e o i / OS são compilados) . A Intel tem seu próprio compilador. Sun / Oracle tem seu próprio compilador no Sun Studio.

Depois, existem fornecedores de compiladores de alto desempenho, como o PathScale e o The Portland Group, cujos compiladores (e bibliotecas OpenMP) são usados ​​para processamento de números.

A Digital Mars também ainda está no mercado. Acredito que Walter Bright tenha a distinção única de ser a única pessoa no planeta que conseguiu criar um compilador C ++ com qualidade de produção (principalmente) sozinho.

Por último, mas não menos importante, temos todos os compiladores proprietários para microcontroladores incorporados. Segundo o IIRC, há mais microcontroladores vendidos a cada ano do que as CPUs de desktop, celular, servidor, estação de trabalho e mainframe que foram vendidas em toda a história da computação combinada. Portanto, esses definitivamente não são produtos de nicho.

Uma menção honrosa é dada ao TruffleC , um intérprete C (!) Executado na JVM (!) Escrito usando a estrutura de intérpretes Truffle AST que é apenas 7% mais lenta que o GCC e o Clang (o que for mais rápido em um determinado parâmetro de referência) em todo o Computer Languages ​​Benchmark Game, e mais rápido do que ambos nos microbenchmarks. Usando o TruffleC, a equipe do Truffle conseguiu que sua versão do JRuby + Truffle executasse extensões Ruby C mais rapidamente do que a implementação real do C Ruby!

Então, essas são 6 implementações, além das listadas, que eu posso citar de cabeça, sem nem mesmo saber nada sobre C.


11
Fora do Microsoft Visual C, a maioria dos compiladores C que você mencionou raramente são usados.
Basile Starynkevitch

6
O MSVC é o grande compilador C ++, mas para C é difícil de usar e fica permanentemente preso no C89; os compiladores de microcontroladores geralmente são específicos de um alvo, presos no C89 e peculiares; TruffleC ainda não parece estar disponível (mas é interessante, obrigado). O Pathscale e o Digital Mars parecem mais o tipo de contra-exemplo que eu estava procurando.
Leushenko 19/02

8
@ Mario, meu significado não é que C89 esteja quebrado, mas C89 não é a forma atualizada do idioma; e isso significa que existem menos compiladores atualizados .
Leushenko 19/02

6
@ Leushenko MSVC não está permanentemente preso no C89. Houve algumas discussões e mais recursos do C99 devem ser adicionados. Para iniciantes, a maior parte da biblioteca C99 é suportada no MSVC 2015 e alguns recursos de idioma também (principalmente os itens necessários para o C ++ 11).
Morwenn

5
@ Morganwenn: a política da Microsoft parece ser a de que o C99 não resolve nenhum problema que o C ++ ainda não havia resolvido e que, se você estiver fazendo programação do sistema, deverá usar o subconjunto do C ++ do tipo C (qualquer coisa que não exija o tempo de execução ou onde você não pode controlar onde o compilador colocará as coisas - importante se você precisar garantir que o código ou os dados não sejam paginados nos estados em que a paginação está desabilitada). Os únicos recursos do C99 serão os itens exigidos em especificações posteriores do C ++ e aqueles que não são capazes de implementar.
precisa

8

Quantos compiladores você precisa?

Se eles tiverem conjuntos de recursos diferentes, você cria um problema de portabilidade. Se eles são comoditizados, você escolhe o "padrão" (GCC, Clang ou VS). Se você se preocupa com os últimos 5% de desempenho, tem uma referência.

Se você estiver trabalhando com linguagem de programação de maneira recreativa ou para fins de pesquisa, é provável que esteja em uma linguagem mais moderna. Daí a proliferação de compiladores de brinquedos para Scheme e ML. Embora o OCaml pareça estar recebendo alguma tração para usos não acadêmicos que não são de brinquedos.

Observe que isso varia muito de acordo com o idioma. Java possui essencialmente a cadeia de ferramentas Sun / Oracle e a GNU. O Python possui vários compiladores, nenhum dos quais é realmente respeitado em comparação com o intérprete padrão. O Rust and Go possui exatamente uma implementação cada. C # tem Microsoft e Mono.


11
É óbvio que existem razões mais interessantes para desenvolver um compilador ML ... Eu apenas pensei que a comunidade C sendo provavelmente três ordens de magnitude maior equilibraria esse efeito. Mas você pode estar certo, 1000 * 0ainda é 0.
Leushenko

A criação de um novo compilador geralmente está vinculada à fragmentação da comunidade (causada ou causada). Por exemplo, o mantenedor egcs vs gcc é dividido. Além disso, a compatibilidade da fonte C tende a ficar abaixo de 100%.
Pjc50

@ pjc50: A maneira como o padrão é escrito efetivamente subdivide C em vários dialetos disjuntos, com base em coisas como o tipo básico de int, e exigirá que compiladores diferentes interpretem o mesmo código-fonte de maneiras muito diferentes.
Supercat

5
Eu acredito que o Go tem duas implementações (a 6g/ 8g/… toolchain e gccgo). Também costumava haver uma implementação comercial proprietária muito interessante chamada erGo, que era a) uma implementação nativa do Go no Windows em um momento em que nem o gccgo nem o compilador Go original funcionavam muito bem no Windows, b) uma empresa que aposta no Go há muito tempo antes mesmo de se tornar 1.0, e c) a primeira implementação do Go escrita em Go (gccgo e 6g / 8g são escritos em C). Tanto o projeto quanto a empresa desapareceram antes mesmo de sair do beta fechado.
Jörg W Mittag

6

O C / C ++ é único entre as linguagens compiladas, pois possui três implementações principais de uma especificação comum.

Seguindo a regra de descartar qualquer coisa que não seja muito usada, todos os outros idiomas compilados têm de 0 a 1.

E acho que o javascript é a única razão pela qual você precisa especificar 'compilado'.


2
O rótulo "C" é aplicado a vários idiomas diferentes; alguns definem o código uint16_t a=48000u; unsigned uint32_t b=(a*a)/2;como atribuindo ao bvalor 8192. Alguns o definem como atribuindo 1152000000. Atualmente, ele é considerado um comportamento indefinido e provavelmente armazena 3299483648, mas não faz nenhuma promessa a esse respeito.
Supercat

11
@supercat: Ah, um bom estranho com estouros e regras de promoção de números inteiros. Depende do uso 2ou 2uaparentemente.
Zan Lynx

11
@ZanLynx: Acho que não há casos em que 2 versus 2u sejam legitimamente importantes; o único caso em que sei onde isso importa envolve comportamento indefinido com 2 e 2u.
21815

3
@ supercat: como você obteria um comportamento indefinido /2u? Estouro não assinado é definido (como módulo 2 ^ N para N definido pela implementação), mas a divisão não pode estourar.
MSalters

2
O comportamento indefinido viria da multiplicação de valores que seriam promovidos a assinados int, mas cujo produto não se encaixaria nesse tipo. Coagir esse resultado a int não assinado provavelmente mudaria a interpretação do valor resultante, mas não negaria o Comportamento Indefinido do cálculo anterior.
supercat

5

Então, qual é o seu idioma de destino?

Os compiladores SML geralmente têm como alvo C ou algo como LLVM (ou como visto no seu link, JVM ou JavaScript).

Se você está compilando C, não é porque está indo para a JVM. Você está indo para algo pior que C. Muito pior. E então você pode duplicar esse inferno menor várias vezes para todas as suas plataformas de destino.

E claro, C não é C ++, mas eu diria que é mais próximo de C ++ que de Scheme. Ele tem seu próprio subconjunto de maldade indefinida de comportamento (estou olhando para o tamanho de tipos embutidos). E se você estragar essas minúcias (ou fazê-lo "corretamente", mas inesperadamente), há décadas de código existente em sistemas vitais que lhe dirão o quão terrível você é. Se você estragar um compilador SML, ele simplesmente não funcionará - e alguém pode perceber. Algum dia.


SML / NJ e PolyML são ambos compilar para código de máquina ...
Basile Starynkevitch

2
Como é o tamanho int "Comportamento indefinido"? E por que o UB seria um fardo para os fornecedores de compiladores? O único ônus real para os gravadores de compilador é que as larguras int são definidas pela implementação, não especificadas, então você precisa documentar o que fez.
MSalters

@MSalters Na realidade, os escritores de compiladores de uma plataforma estabelecida têm o ônus de corresponder ao que os outros anteriores a eles. Às vezes, isso é documentado e padronizado, às vezes não. É fácil encontrar o tamanho de um int, mas é mais difícil encontrar o que é feito com valores de registro e onde os argumentos são armazenados ao chamar uma função (que pode mudar dependendo dos tipos de argumentos e do tipo de retorno da função), regras de layout da estrutura, etc
Random832

@MSalters A maioria das pessoas espera intter 32 ou 64 bits, mas pode ser tão pequeno quanto 16 bits. Não é difícil produzir um número fora da faixa [−32767, +32767]e o intexcesso é UB. Também há char/ shortsendo promovido int ou unsigned int dependendo de se intpode representar todos os valores do tipo original, o que pode desencadear ainda mais uma conversão de intpara unsigned intse os operandos tivessem tipos diferentes e tivessem sido convertidos de maneira diferente, além de potencialmente outra conversão ao atribuir o resultado a uma variável .
Doval

@MSalters Há margem de manobra suficiente no tamanho dos tipos padrão e conversões implícitas suficientes que eu apostaria que, para praticamente qualquer programa C não trivial, há uma escolha de tamanhos inteiros legais que farão com que ele faça algo errado ou indeterminado comportamento.
D
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.