Pourquoi y a-t-il si peu de compilateurs C?

72

C est l’une des langues les plus utilisées au monde. Il représente une énorme proportion du code existant et continue à être utilisé pour une grande quantité de nouveau code. Il est tellement apprécié par ses utilisateurs, il est tellement répandu que pouvoir exécuter C est pour beaucoup la définition informelle d’une plate-forme , et ses fans le félicitent d’être un "petit" langage avec un ensemble de fonctionnalités relativement propres.

Alors où sont tous les compilateurs?

Sur le bureau, il y en a (de manière réaliste) deux : GCC et Clang. En y réfléchissant quelques secondes, vous vous souviendrez probablement qu'Intel existe également. Il y en a une poignée d'autres, beaucoup trop obscurs pour qu'une personne moyenne puisse les nommer et ne voulant presque pas supporter une version linguistique récente (ou souvent même un sous-ensemble linguistique bien défini, juste un "sous-ensemble"). La moitié des membres de cette liste sont des notes de bas de page historiques; la plupart des autres sont très spécialisés et n'implémentent toujours pas le langage complet. Très peu semblent réellement être open-source.

Scheme et Forth - d’autres petites langues aimées par leurs fans - ont probablement plus de compilateurs que d’utilisateurs réels. Même quelque chose comme SML a plus d'implémentations «sérieuses» à choisir que C. Alors que l'annonce d' un nouveau compilateur C (inachevé) visant à la vérification entraîne des réactions plutôt négatives, et que les implémentations anciennes ont du mal à obtenir suffisamment de contributeurs pour même rattraper C99.

Pourquoi? L'application de C est-elle si difficile? Ce n'est pas C ++. Les utilisateurs ont-ils simplement une idée très biaisée du groupe de complexité auquel il appartient (c.-à-d. Qu'il est plus proche de C ++ que de Scheme)?


la source
61
MSVC compte toujours, en tant que compilateur C89 au moins. Probablement plus populaire qu'Intel même.
Rufflewind
22
Wikipedia répertorie pas mal de compilateurs C. Ils deviennent très fréquents lorsque vous vous trouvez dans le royaume intégré.
113
combien de compilateurs avez-vous besoin pour compiler votre code C?
Bryan Chen
76
La question est basée sur une fausse prémisse. Analog Devices, armcc, le compilateur C de Bruce, le compilateur Cross Bare-C, le compilateur Borland, le compilateur Clang, le compilateur Cosmic C, le compilateur CodeWarrior, le compilateur dokto, le compilateur Ericsson, et je ne suis même pas sorti de la Cinq premières lettres de l'alphabet encore. Il y a un nombre incroyablement élevé de compilateurs C. La question est "pourquoi y a-t-il si peu de compilateurs C, si nous ne comptons pas ces plusieurs dizaines comme de vrais compilateurs C?" Vous avez défini la grande majorité des compilateurs C comme non intéressants, raison pour laquelle ils ne sont pas très nombreux.
Eric Lippert
19
"Pourquoi" les questions sont mauvaises pour ce site dans le meilleur des cas, et "pourquoi pas?" les questions sont pires. Si je vous rencontrais à une fête et demandais "Alors, pourquoi ne courez-vous pas les voiliers?" Je pense que vous trouverez à juste titre que c'est une question étrange. Vous n'avez pas besoin de fournir une justification pour NE PAS vous engager dans un passe-temps techniquement difficile, physiquement risqué et très coûteux. Écrire un logiciel non trivial est coûteux, difficile et risqué et nécessite donc un facteur de motivation énorme . Une meilleure question serait "pourquoi y a-t-il autant de compilateurs C?" Il est surprenant qu'il y en ait plus d'un.
Eric Lippert

Réponses:

153

Aujourd'hui, vous avez besoin d' un compilateur C réel pour être un compilateur d'optimisation , notamment parce que C n'est plus une langue proche du matériel, car actuels processeurs sont complexes incroyablement ( hors-ordre , pipelinée , superscalaire , avec complexes caches et TLB , donc besoin d’ ordonnancement des instructions , etc ...). Les processeurs x86 actuels ne ressemblent pas aux processeurs i386 du siècle précédent, même s'ils sont capables d'exécuter le même code machine. Voir que le C n'est pas un langage de bas niveau (votre ordinateur n'est pas un PDP-11 rapide), article de David Chisnall.

Peu de gens utilisent des compilateurs C naïfs, non optimiseurs, tels que tinycc ou nwcc , car ils produisent un code plusieurs fois plus lent que ce que les compilateurs optimiseurs peuvent générer.

Coder un compilateur d'optimisation est difficile. Notez que GCC et Clang optimisent tous deux la représentation de code "neutre par rapport au langage source" (Gimple pour GCC, LLVM pour Clang). La complexité d'un bon compilateur C n'est pas en phase d'analyse!

En particulier, créer un compilateur C ++ n’est pas beaucoup plus difficile que de faire un compilateur C: analyser C ++ et le transformer en représentation de code interne est complexe (car la spécification C ++ est complexe), mais il est bien compris, mais les éléments d’optimisation sont encore plus complexes. complexe (à l’intérieur de GCC: les optimisations moyennes, neutres en langage source et en processeur cible, constituent le composant principal du compilateur, le reste étant équilibré entre des interfaces pour plusieurs langues et des interfaces pour plusieurs processeurs). Par conséquent, la plupart des compilateurs C optimiseurs sont également capables de compiler d'autres langages, tels que C ++, Fortran, D, ... Les parties spécifiques à C ++ de GCC représentent environ 20% du compilateur ...

De plus, C (ou C ++) est si largement utilisé que les utilisateurs s'attendent à ce que leur code soit compilable même s'il ne suit pas exactement les normes officielles, qui ne définissent pas assez précisément la sémantique du langage (chaque compilateur peut donc avoir sa propre interprétation). de celui-ci). Regardez aussi dans le compilateur C prouvé CompCert , et l' analyseur statique Frama-C , qui se soucient de la sémantique plus formelle de C.

Et les optimisations sont un phénomène de longue haleine : il est facile d'implémenter quelques optimisations simples, mais elles ne rendront pas un compilateur compétitif! Vous devez implémenter de nombreuses optimisations, et les organiser et les combiner intelligemment, pour obtenir un compilateur réel compétitif. En d'autres termes, un compilateur d'optimisation réel doit être un logiciel complexe. BTW, GCC et Clang / LLVM disposent de plusieurs générateurs de code C / C ++ spécialisés internes. Et les deux sont de grosses bêtes (plusieurs millions de lignes de code source, avec un taux de croissance de plusieurs pour cent par an) avec une importante communauté de développeurs (quelques centaines de personnes travaillant principalement à temps plein ou au moins à mi-temps).

Notez qu’il n’existe pas (à ma connaissance) de compilateur C multithreads, même si certaines parties d’un compilateur pourraient être exécutées en parallèle (par exemple, optimisation intra-procédurale, allocation de registre, ordonnancement des instructions, etc.). Et construire en parallèle avec make -jn'est pas toujours suffisant (surtout avec LTO ).

En outre, il est difficile d’obtenir des fonds pour coder un compilateur C à partir de rien, et cet effort doit durer plusieurs années. Enfin, la plupart des compilateurs C ou C ++ sont aujourd'hui des logiciels libres (il n'y a plus de marché pour les nouveaux compilateurs propriétaires vendus par les startups) ou du moins sont des produits monopolistiques (comme Microsoft Visual C ++ ), et être un logiciel libre est presque indispensable pour les compilateurs ( car ils ont besoin des contributions de nombreuses organisations différentes).

Je serais ravi d'obtenir des fonds pour travailler sur un compilateur C à partir de rien en tant que logiciel libre, mais je ne suis pas assez naïf pour croire que c'est possible aujourd'hui!

Basile Starynkevitch
la source
14
(there is no more a market for proprietary compilersDites-le à l'équipe de Visual Studio ...
Mason Wheeler
18
Microsoft a le monopole. Je voulais dire que les petites entreprises développant de nouveaux compilateurs C n'en vendraient pas beaucoup. Pouvez-vous nommer un concurrent récent propriétaire de MSVC?
Basile Starynkevitch le
12
Il existe de nombreux compilateurs propriétaires dans le monde HPC. PGCC, NAG et ICC sont les plus largement utilisés.
Davidmh
37
@MasonWheeler: VS est offert gratuitement de nos jours (comme dans la bière). Les versions non libres ajoutent des outils, mais le compilateur C de VS2013 est identique dans toutes les versions. Il n'y a pas de marché, pas même pour eux.
MSalters
3
Mais GCC et LLVM fonctionnent tous deux sur des représentations beaucoup plus basses et optimisent de la même manière le code C ++ & C (& Ada & Fortran, pour GCC). Je dirais au contraire que C ++ nécessite plus d'optimisation (notamment lors de la compilation de code utilisant sa STL) que C!
Basile Starynkevitch
70

J'aimerais contester votre hypothèse sous-jacente selon laquelle il n'y a qu'un petit nombre d'implémentations en C.

Je ne connais même pas C, je n'utilise pas C, je ne suis pas membre de la communauté C et pourtant, même si j'en connais beaucoup plus que les quelques compilateurs que vous avez mentionnés.

D'abord et avant tout, il y a le compilateur qui gomme probablement complètement GCC et Clang sur le bureau: Microsoft Visual C. En dépit des avancées faites par OSX et Linux sur le bureau, et la part de marché qu'iOS et Android ont "volée" loin des anciens utilisateurs de bureau traditionnels, Windows est toujours le système d'exploitation dominant et la majorité des programmes C de bureau Windows sont probablement compilés à l'aide d'outils Microsoft.

Traditionnellement, chaque fournisseur de système d'exploitation et chaque fournisseur de puces disposaient de leurs propres compilateurs. Microsoft, en tant que fournisseur de système d’exploitation, dispose de Microsoft Visual C. IBM, en tant que fournisseur de système d’exploitation et fournisseur de puces, comporte XLC (qui est le compilateur système par défaut pour AIX et le compilateur avec lequel AIX et i / OS sont compilés) . Intel a son propre compilateur. Sun / Oracle ont leur propre compilateur dans Sun Studio.

Viennent ensuite les éditeurs de compilateurs hautes performances tels que PathScale et The Portland Group, dont les compilateurs (et les bibliothèques OpenMP) sont utilisés pour la numérotation.

Digital Mars est également toujours en activité. Je crois que Walter Bright a la particularité d'être la seule personne sur la planète à avoir réussi à créer lui-même un compilateur C ++ de qualité production.

Enfin, nous avons tous les compilateurs exclusifs pour les microcontrôleurs intégrés. IIRC, le nombre de microcontrôleurs vendus chaque année est supérieur à celui des processeurs de bureau, mobiles, serveurs, stations de travail et ordinateurs centraux, vendus depuis le début de l’histoire de l’informatique combinée. Donc, ce ne sont certainement pas des produits de niche.

Une mention honorifique revient à TruffleC , un interprète C (!) Fonctionnant sur la JVM (!) Écrit à l’aide du framework d’interpréteur Truffle AST qui est seulement 7% plus lent que GCC et Clang (celui qui est le plus rapide sur un repère donné) sur le Jeu de benchmark de langues informatiques, et plus rapide que les deux sur les microbenchmarks. En utilisant TruffleC, l'équipe de Truffle a pu obtenir que sa version de JRuby + Truffle exécute des extensions Ruby C plus rapidement que l'implémentation réelle de C Ruby!

Donc, ce sont 6 implémentations en plus de celles que vous avez énumérées et que je peux nommer à mon insu, sans même rien savoir de C.

Jörg W Mittag
la source
1
En dehors de Microsoft Visual C, la plupart des compilateurs C que vous mentionnez sont rarement utilisés.
Basile Starynkevitch le
6
MSVC est le gros compilateur C ++, mais pour C, il est difficile à utiliser et reste bloqué en permanence dans C89; Les compilateurs de microcontrôleurs sont généralement spécifiques à une cible, bloqués dans C89 et bizarres; TruffleC ne semble pas encore disponible (mais est intéressant, merci). Pathscale et Digital Mars ressemblent plus au genre de contre-exemples que je cherchais.
Leushenko
8
@Mario, je ne veux pas dire que C89 est cassé, mais C89 n'est pas la forme à jour du langage; et cela signifie que moins de compilateurs mis à jour existent.
Leushenko
6
@ Leushenko MSVC n'est pas bloqué en permanence dans C89. Il y a eu des discussions et d'autres fonctionnalités du C99 devraient être ajoutées. Pour commencer, la plupart de la bibliothèque C99 est prise en charge à partir de MSVC 2015 et quelques fonctionnalités du langage (bien que, principalement, les éléments nécessaires à C ++ 11).
Morwenn
5
@Morwenn: La politique de Microsoft semble être que C99 ne résout aucun problème que C ++ n'a pas encore résolu, et que si vous effectuez de la programmation système, vous devez utiliser le sous-ensemble C-like de C ++ (tout ce qui ne nécessite pas l'exécution ou où vous ne pouvez pas contrôler où le compilateur va mettre les choses - important si vous devez vous assurer que le code ou les données ne sont pas paginés sur des états où la pagination est désactivée). Les seules fonctionnalités de C99 seront les éléments requis dans les spécifications C ++ ultérieures, et celles qui ne demandent pas à être mises en œuvre.
Mike Dimmick
8

De combien de compilateurs avez-vous besoin?

S'ils ont des ensembles de fonctionnalités différents, vous créez un problème de portabilité. Si elles sont banalisées, vous choisissez soit le "défaut" (GCC, Clang ou VS). Si vous vous souciez des 5% restants, vous avez un point de repère.

Si vous travaillez en langage de programmation de manière récréative ou à des fins de recherche, vous utiliserez probablement une langue plus moderne. D'où la multiplication des compilateurs de jouets pour Scheme et ML. Bien que OCaml semble gagner du terrain pour des utilisations non académiques non jouets.

Notez que cela varie beaucoup selon la langue. Java a essentiellement les outils Sun / Oracle et GNU. Python a divers compilateurs dont aucun n’est vraiment respecté par rapport à l’interprète standard. Rust et Go ont exactement une implémentation chacun. C # a Microsoft et Mono.

pjc50
la source
1
Il est évident qu'il existe des raisons plus intéressantes de développer un compilateur ML ... Je pensais simplement que la communauté C étant probablement plus grande de trois ordres de grandeur, cet effet serait compensé. Mais vous avez peut-être raison, 1000 * 0c'est toujours 0.
Leushenko
La création d'un nouveau compilateur est souvent liée à la fragmentation de la communauté (causée par ou causant). Par exemple, le responsable egcs vs gcc est scindé. En outre, la compatibilité de la source C tend à être inférieure à 100%.
pjc50
@ pjc50: La manière dont la norme est écrite divise efficacement C en un certain nombre de dialectes disjoints basés sur des éléments tels que le type de base de int, et obligera différents compilateurs à interpréter le même code source de manière très différente.
Supercat
5
Je crois que Go a deux implémentations (la chaîne d'outils 6g/ 8g/… et gccgo). Il existait également une implémentation commerciale propriétaire très intéressante appelée erGo, qui était a) une implémentation Windows native de Go à un moment où ni gccgo ni le compilateur Go d'origine ne fonctionnaient très bien sous Windows, b) une entreprise pariant sur Go, longue avant même de devenir 1.0, et c) la première mise en œuvre de Go écrite en Go (gccgo et 6g / 8g sont tous deux écrits en C). Le projet et la société ont toutefois disparu avant même de sortir de la bêta fermée.
Jörg W Mittag
6

C / C ++ est unique parmi les langages compilés en ce qu'il a 3 implémentations majeures d'une spécification commune.

Selon la règle de rejeter tout ce qui est peu utilisé, tout autre langage compilé a un score de 0 à 1.

Et je pense que javascript est la seule raison pour laquelle vous devez spécifier «compilé».

soru
la source
2
L'étiquette "C" est appliquée à un certain nombre de langues différentes; certains définissent le code uint16_t a=48000u; unsigned uint32_t b=(a*a)/2;comme affectant bla valeur 8192. Certains le définissent comme affectant 1152000000. La plupart du temps le considère comme un comportement indéfini et susceptible de stocker 3299483648 mais ne fait aucune promesse à cet égard.
Supercat
1
@supercat: Ah, un bon bizarre avec débordements et règles de promotion d'entier. Cela dépend de l'utilisation 2ou 2uapparemment.
Zan Lynx
1
@ZanLynx: Je ne pense pas qu'il y ait de cas où 2 contre 2u comptent légitimement ; le seul cas où je sais où cela pourrait avoir de l'importance implique un comportement indéfini avec 2 et 2u.
Supercat
3
@supercat: comment obtiendriez-vous un comportement indéfini /2u? Le débordement non signé est défini (en tant que modulo 2 ^ N pour le N défini par la mise en oeuvre), mais la division ne peut même pas déborder.
MSalters
2
Le comportement indéfini proviendrait de la multiplication de valeurs qui seraient promues à signées int, mais dont le produit ne rentrerait pas dans ce type. Le fait de forcer ce résultat vers un entier non signé signifierait probablement que l'interprétation de la valeur résultante serait modifiée, mais n'annulerait pas le comportement non défini du calcul précédent.
Supercat
5

Alors, quelle est votre langue cible?

Les compilateurs SML ciblent souvent C ou quelque chose comme LLVM (ou comme vous le voyez dans votre lien, la JVM ou JavaScript).

Si vous compilez C, ce n'est pas parce que vous allez sur la JVM. Vous allez à quelque chose de pire que C. Bien pire. Et ensuite, vous pouvez dupliquer cet enfer mineur un tas de fois pour toutes vos plates-formes cibles.

Et bien sûr, C n'est pas C ++, mais je dirais que c'est plus proche de C ++ que de Scheme. Il a son propre sous-ensemble de pervers comportements indéfinis (je regarde votre taille de types intégrés). Et si vous bousillez ces minuties (ou si vous le faites "correctement" mais de manière inattendue), vous disposez alors de décennies de code existant sur des systèmes vitaux qui vous diront à quel point vous êtes terrible. Si vous bousillez un compilateur SML, cela ne fonctionnera tout simplement pas - et quelqu'un pourrait s'en rendre compte. Un jour.

Telastyn
la source
SML / NJ et PolyML compilent tous les deux en code machine ...
Basile Starynkevitch, le
2
Comment est la taille int "Undefined Behavior"? Et pourquoi UB serait-il un fardeau pour les vendeurs de compilateurs? Le seul véritable fardeau pour les rédacteurs de compilateur est que les largeurs int soient définies par la mise en œuvre, et non indéterminées. Vous devez donc documenter ce que vous avez fait.
MSalters
@MSalters En réalité, les rédacteurs de compilateurs d'une plate-forme établie ont le fardeau de faire correspondre ceux qui les ont précédés. Parfois, cela est documenté et normalisé, parfois non. Il est facile de trouver la taille d’un int, mais plus difficile de savoir ce qui est fait avec les valeurs de registre et où les arguments sont stockés lors de l’appel d’une fonction (qui peut changer en fonction des types d’argument et du type de retour de la fonction), des règles de mise en forme, etc.
Random832
@MSalters La plupart des gens s'attendent intà avoir 32 ou 64 bits, mais cela peut être aussi petit que 16 bits. Ce n'est pas difficile du tout de produire un nombre en dehors de la plage [−32767, +32767]et le intdébordement est UB. Il y a aussi char/ shortse promu int ou unsigned int selon que intpeut représenter chaque valeur du type d' origine, ce qui peut encore déclencher une conversion à partir intde unsigned intsi les opérandes avaient différents types et se sont convertis différemment, plus potentiellement une autre conversion lorsque vous attribuez le résultat à une variable .
Doval
@MSalters La taille des types standard et les conversions implicites sont suffisantes pour que je parie que pour tout programme C non trivial, il existe un choix de tailles entières légales qui le ferait mal ou non indéfini. comportement.
Doval