C est l'une des langues les plus utilisées au monde. Il représente une énorme proportion du code existant et continue d'être utilisé pour une grande quantité de nouveau code. Il est aimé par ses utilisateurs, il est si largement porté que pouvoir exécuter C est pour beaucoup la définition informelle d'une plate-forme , et est salué par ses fans pour être un "petit" langage avec un ensemble de fonctionnalités relativement propre.
Alors, où sont tous les compilateurs?
Sur le bureau, il y a (de façon 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 quelques autres, bien trop obscurs pour que la personne moyenne puisse les nommer et ne se souciant presque pas universellement de prendre en charge une version linguistique récente (ou souvent même un sous-ensemble linguistique bien défini, juste "un sous-ensemble"). La moitié de les 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 en fait être open-source.
Scheme and Forth - d'autres petits langages appréciés 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 de n nouveau compilateur C (inachevé) visant à vérification voit en fait des réponses assez négatives, et implémentations vétérans du mal à obtenir suffisamment de contributeurs pour même rattraper C99.
Pourquoi? La mise en œuvre de C est-elle si difficile? Ce n'est pas du C++. Les utilisateurs ont-ils simplement une idée très biaisée du groupe de complexité dans lequel ils se trouvent (c'est-à-dire qu'il est en fait plus proche de C++ que de Scheme)?
Aujourd'hui, vous avez besoin d'un vrai compilateur C pour être compilateur d'optimisation , notamment parce que C n'est plus un langage proche du matériel, car les processeurs actuels sont incroyablement complexes (- hors service , pipelined , superscalar , with complex caches & TLB , nécessitant donc ordonnancement des instructions , etc ...). Les processeurs x86 d'aujourd'hui ne sont pas comme les processeurs i386 du siècle précédent, même si les deux sont capables d'exécuter le même code machine. Voir le C n'est pas un langage de bas niveau (Votre ordinateur n'est pas un PDP-11 rapide) papier par David Chisnall.
Peu de gens utilisent des compilateurs C naïfs non optimisateurs comme tinycc ou nwcc , car ils produisent du code qui est plusieurs fois plus lent que ce que les compilateurs optimiseurs peuvent donner.
Le codage d'un compilateur d'optimisation est difficile. Notez que GCC et Clang optimisent une représentation de code "neutre pour le langage source" (Gimple pour GCC, LLVM pour Clang). La complexité d'un bon compilateur C n'est pas en phase d'analyse!
En particulier, faire un compilateur C++ n'est pas beaucoup plus difficile que de faire un compilateur C: analyser C++ et le transformer en une représentation de code interne est complexe (car la spécification C++ est complexe), mais est bien compris, mais les parties d'optimisation sont encore plus complexe (à l'intérieur de GCC: les optimisations milieu de gamme, neutre en langage source et processeur cible, forment la majorité du compilateur, le reste étant équilibré entre les frontaux pour plusieurs langues et back-end pour plusieurs processeurs). Par conséquent, la plupart des compilateurs C optimisants sont également capables de compiler d'autres langages, comme 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 gens 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 (donc chaque compilateur peut avoir sa propre interprétation de celui-ci). Regardez aussi le compilateur C CompCert éprouvé, et l'analyseur statique Frama-C , qui se soucient de plus formel sémantique de C.
Et les optimisations sont un phénomène longue traîne : mettre en œuvre quelques optimisations simples est facile, mais elles ne rendront pas un compilateur compétitif! Vous devez implémenter de nombreuses optimisations différentes, les organiser et les combiner intelligemment pour obtenir un compilateur réel qui soit compétitif. En d'autres termes, un compilateur d'optimisation du monde réel doit être un logiciel complexe. BTW, GCC et Clang/LLVM ont plusieurs générateurs de code C/C++ spécialisés internes. Et les deux sont d'énormes bêtes (plusieurs millions de lignes de code source, avec un taux de croissance de plusieurs pour cent chaque année) avec une grande communauté de développeurs (quelques centaines de personnes, travaillant principalement à plein temps ou au moins à mi-temps).
Notez qu'il n'y a pas (à ma connaissance) de compilateur C multi-thread, même si certains des parties d'un compilateur pourraient être exécutées en parallèle (par exemple, optimisation intra-procédurale, allocation de registre, ordonnancement d'instructions ...). Et la construction parallèle avec make -j
n'est pas toujours suffisant (surtout avec LTO ).
En outre, il est difficile d'obtenir des fonds pour coder un compilateur C à partir de zéro, et un tel effort doit durer plusieurs années. Enfin, la plupart des compilateurs C ou C++ sont des logiciels libres aujourd'hui (il n'y a plus de marché pour les nouveaux compilateurs propriétaires vendus par les startups) ou au moins sont des produits monopolistiques (comme Microsoft Visual C++ ), et étant un logiciel libre les logiciels sont presque nécessaires pour les compilateurs (car ils ont besoin des contributions de nombreuses organisations différentes).
Je serais ravi d'obtenir du financement pour travailler sur un compilateur C à partir de zéro en tant que logiciel libre, mais je ne suis pas assez naïf pour croire que c'est possible aujourd'hui!
Je voudrais contester votre hypothèse sous-jacente selon laquelle il n'y a qu'un petit nombre d'implémentations 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 j'en sais bien plus que les quelques compilateurs que vous avez mentionnés.
D'abord et avant tout, il y a le compilateur qui éclipse probablement complètement GCC et Clang sur le bureau: Microsoft Visual C.Malgré les percées qu'OSX et Linux ont faites sur le bureau, et la part de marché qu'iOS et Android s'est "volé" aux anciens utilisateurs de bureau traditionnels, Windows est toujours l'OS de bureau 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 avaient leurs propres compilateurs. Microsoft, en tant que fournisseur de système d'exploitation, a Microsoft Visual C. IBM, en tant que fournisseur de système d'exploitation et fournisseur de puces, a 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.
Ensuite, il y a les fournisseurs de compilateurs hautes performances comme PathScale et The Portland Group, dont les compilateurs (et les bibliothèques OpenMP) sont utilisés pour le calcul numérique.
Digital Mars est également toujours en activité. Je crois que Walter Bright a la distinction unique d'être la seule personne sur la planète qui a réussi à créer un compilateur C++ de qualité production (principalement) par lui-même.
Enfin, nous avons tous les compilateurs propriétaires pour les microcontrôleurs intégrés. IIRC, il y a plus de microcontrôleurs vendus chaque année que de CPU de bureau, mobile, serveur, station de travail et mainframe dans toute l'histoire de l'informatique combinée. Donc, ce ne sont certainement pas des produits de niche.
Une mention honorifique va à TruffleC , un interpréteur C (!) Fonctionnant sur la JVM (!) Écrit à l'aide de la truffe AST framework d'interpréteur qui est seulement 7% plus lent que GCC et Clang (selon le plus rapide sur n'importe quel benchmark particulier donné) à travers le jeu de benchmark des langages informatiques, et plus rapide que les deux sur les microbenchmarks. En utilisant TruffleC, le L'équipe de Truffle a pu obtenir sa version de JRuby + Truffle pour exécuter les extensions Ruby C plus rapidement que l'implémentation C Ruby!)!
Donc, ce sont 6 implémentations en plus de celles que vous avez énumérées que je peux nommer du haut de ma tête, sans même rien savoir de C.
De combien de compilateurs avez-vous besoin?
S'ils ont des jeux de fonctionnalités différents, vous créez un problème de portabilité. S'ils sont standardisés, vous choisissez soit le "défaut" (GCC, Clang ou VS). Si vous vous souciez de la dernière performance de 5%, vous avez un point de référence.
Si vous effectuez un travail de langage de programmation à des fins récréatives ou à des fins de recherche, il est probable que ce soit dans un langage plus moderne. D'où la prolifération des compilateurs jouets pour Scheme et ML. Bien que l'OCaml semble obtenir une certaine traction pour des utilisations non académiques non-jouets.
Notez que cela varie beaucoup selon la langue. Java a essentiellement la chaîne d'outils Sun/Oracle et la GNU one. Python a divers compilateurs dont aucun n'est vraiment respecté) par rapport à l'interpréteur standard. Rust et Go ont exactement une implémentation chacun. C # a Microsoft et Mono.
C/C++ est unique parmi les langages compilés en ce qu'il a 3 implémentations principales d'une spécification commune.
En suivant la règle de rejeter tout ce qui n'est pas beaucoup utilisé, toutes les autres langues compilées ont 0 à 1.
Et je pense que javascript est la seule raison pour laquelle vous devez spécifier "compilé".
Quelle est donc votre langue cible?
Les compilateurs SML ciblent souvent C ou quelque chose comme LLVM (ou comme on le voit 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 pire que C. Bien pire. Et puis vous pouvez dupliquer cet enfer mineur plusieurs fois pour toutes vos plates-formes cibles.
Et bien sûr, C n'est pas C++, mais je dirais qu'il est plus proche de C++ que de Scheme. Il a son propre sous-ensemble de méchanceté comportementale indéfinie (je regarde la taille des types intégrés). Et si vous bousiller ces détails (ou le faire "correctement" mais de manière inattendue), vous avez des décennies de code existant sur les systèmes vitaux qui vous diront à quel point vous êtes terrible. Si vous bousiller un compilateur SML, cela ne fonctionnera tout simplement pas - et quelqu'un pourrait remarquer. Un jour.