Comment se fait-il que les compilateurs soient si fiables?

64

Nous utilisons quotidiennement les compilateurs comme si leur exactitude était acquise, mais les compilateurs sont aussi des programmes et peuvent potentiellement contenir des bogues. Je me suis toujours interrogé sur cette robustesse infaillible. Avez-vous déjà rencontré un bogue dans le compilateur lui-même? Qu'est-ce que c'était et comment avez-vous réalisé que le problème était dans le compilateur lui-même?

... et comment rendent- ils les compilateurs si fiables?

EpsilonVector
la source
16
Eh bien, ils compilent le compilateur dedans ...
Michael K
31
Ils ne sont pas infaillibles. Il y a des bogues de compilateur - c'est juste qu'ils sont très rares.
ChrisF
5
Les bogues deviennent plus rares à mesure que vous descendez dans la pile de code: les bogues d'application sont plus courants que les bogues de compilateur. Les bogues du compilateur sont plus courants que les bogues du processeur (microcode). C'est en fait une bonne nouvelle: pouvez-vous imaginer si c'était l'inverse?
Fixee
Vous pourriez apprendre quelque chose en observant comment un compilateur qui fait un grand nombre de bugs (comme sdcc!) Est différent d'un compilateur comme gcc qui est beaucoup plus robuste et fiable.
Ben Jackson
5
VC ++ 6 avait un bug.
Mateen Ulhaq

Réponses:

97

Ils sont testés de manière approfondie via des milliers, voire des millions de développeurs, au fil du temps.

De plus, le problème à résoudre est bien défini (par une spécification technique très détaillée). Et la nature de la tâche se prête facilement aux tests unitaires / système. C'est-à-dire qu'il s'agit essentiellement de traduire une entrée textuelle dans un format très spécifique pour une sortie dans un autre type de format bien défini (une sorte de code octet ou de code machine). Il est donc facile de créer et de vérifier des cas de test.

De plus, les bogues sont généralement faciles à reproduire: hormis les informations exactes sur la plate-forme et la version du compilateur, vous n'avez généralement besoin que d'un morceau de code d'entrée. Sans compter que les utilisateurs du compilateur (étant les développeurs eux-mêmes) ont tendance à donner des rapports de bogues beaucoup plus précis et détaillés que tout utilisateur d'ordinateur moyen :-)

Péter Török
la source
32
De plus, une bonne partie du code du compilateur peut probablement s’avérer correcte.
biziclop
@biziclop, bon point, c’est une autre conséquence de la nature particulière de la tâche.
Péter Török
Le premier compilateur complet a été écrit en 1957 par John Backus pour le langage FORTRAN. La technologie du compilateur a donc plus de 50 ans. Nous avons eu pas mal de temps pour bien faire les choses, même si, comme d'autres le soulignent, les compilateurs ont des bogues.
leed25d
@biziclop, en fait, certains composants comme les lexers et les analyseurs syntaxiques peuvent même être générés automatiquement à partir d'une grammaire, ce qui réduit encore le risque de bogues (à condition que le générateur lexer / analyseur syntaxique soit robuste - ce qu'ils sont généralement, pour les mêmes raisons que celles énumérées ci-dessus) .
Péter Török
2
@ Péter: Les générateurs Lexer / parser semblent plutôt rares dans les compilateurs les plus largement utilisés - la plupart écrivent lexer et l’analyseur à la main pour diverses raisons, notamment la rapidité et l’absence d’un générateur d’analyseur / lexer suffisamment intelligent pour le langage en question (par exemple, C ).
61

En plus de toutes les bonnes réponses à ce jour:

Vous avez un "biais d'observateur". Vous n'observez pas de bugs et vous supposez donc qu'il n'y en a pas.

Je pensais comme toi. Ensuite, j'ai commencé à écrire des compilateurs de manière professionnelle, et laissez-moi vous dire qu'il y a beaucoup de bugs là-dedans!

Vous ne voyez pas les bogues parce que vous écrivez un code équivalent à 99,999% du reste du code écrit. Vous écrivez probablement du code parfaitement normal, simple et clairement correct, qui appelle des méthodes et exécute des boucles sans rien faire de bizarre ou bizarre, car vous êtes un développeur normal qui résout des problèmes commerciaux normaux.

Vous ne voyez pas de bogues de compilateur, car ceux-ci ne figurent pas dans les scénarios de code normaux simples à analyser et faciles à analyser; les bugs sont dans l'analyse de code étrange que vous n'écrivez pas.

J'ai par contre le biais d'observateur opposé. Je vois du code fou toute la journée, et donc pour moi, les compilateurs semblent fourmiller de bogues.

Si vous vous assoyiez avec la spécification de langue de n'importe quel langage et preniez n'importe quelle implémentation de compilateur pour ce langage, et essayiez vraiment de déterminer si le compilateur implémentait exactement la spécification ou non, en vous concentrant sur des cas obscurs, vous découvririez bientôt compilateur des bogues assez fréquemment. Laissez-moi vous donner un exemple, voici un bogue du compilateur C # que j'ai trouvé littéralement il y a cinq minutes.

static void N(ref int x){}
...
N(ref 123);

Le compilateur donne trois erreurs.

  • Un argument ref ou out doit être une variable assignable.
  • La meilleure correspondance pour N (ref int x) comporte des arguments non valides.
  • "Ref" manquant dans l'argument 1.

De toute évidence, le premier message d'erreur est correct et le troisième est un bogue. L'algorithme de génération d'erreur essaie de comprendre pourquoi le premier argument était invalide, il l'examine, voit qu'il s'agit d'une constante et ne retourne pas dans le code source pour vérifier s'il a été marqué "ref"; il suppose plutôt que personne ne serait assez idiot pour marquer une constante comme arbitre et décide que l'arbitre doit être manquant.

Le troisième message d'erreur correct n'est pas clair, mais ce n'est pas ça. En fait, il n'est pas clair si le deuxième message d'erreur est correct non plus. La résolution de surcharge doit-elle échouer ou "ref 123" doit-il être traité comme un argument de référence du type correct? Je vais maintenant devoir y réfléchir et en discuter avec l'équipe de triage afin que nous puissions déterminer quel est le bon comportement.

Vous n'avez jamais vu ce bug parce que vous ne feriez probablement jamais quelque chose d'aussi stupide que d'essayer de passer 123 par réf. Et si vous le faisiez, vous ne remarqueriez probablement même pas que le troisième message d'erreur est absurde, car le premier message est correct et suffisant pour diagnostiquer le problème. Mais j'essaie de faire des choses comme ça, parce que j'essaye de casser le compilateur. Si vous essayiez, vous verriez aussi les bugs.

Eric Lippert
la source
4
Les bons messages d'erreur après le premier sont très difficiles à faire.
Bien sûr, l'énergie doit être mieux dépensée que de rendre les compilateurs complètement "fous"
Homde
2
@ MKO: Bien sûr. Beaucoup de bugs ne sont pas corrigés. Parfois, le correctif coûte si cher et le scénario est tellement obscur que les avantages ne justifient pas le coût. Et parfois, suffisamment de gens en sont venus à s’en remettre au comportement de "boguette" pour le maintenir.
Eric Lippert
mmm ... les bogues qui se retrouvent dans des messages d'erreur sont "corrects". Il est toujours possible de modifier un peu le code pour le faire fonctionner. Qu'en est-il des bogues dans lesquels le compilateur accepte le code source et produit une sortie "incorrecte" conforme à la réalité. C'est effrayant
Gianluca Ghettini
7
@aij: Correct dans le sens de "code C # clairement légal". Par exemple, avez-vous déjà écrit un programme contenant une interface qui hérite de deux interfaces, l’une ayant une propriété et l’autre une méthode du même nom que la propriété? Vite, sans regarder les spécifications: est-ce légal ? Supposons maintenant que vous appelez cette méthode. est-ce ambigu ? Etc. Les gens écrivent du code qui ne fait pas ce qu'ils veulent dire tout le temps. Mais ils n'écrivent que rarement du code où il faudrait être un expert en spécification pour dire s'il s'agit même de C # légal.
Eric Lippert
52

Vous plaisantez j'espère? Les compilateurs ont aussi des bugs, des charges vraiment.

GCC est probablement le compilateur open source le plus célèbre de la planète et jetez un œil à sa base de données de bogues: http://gcc.gnu.org/bugzilla/buglist.cgi?product=gcc&component=c%2B%2B&resolution=-- -

Entre GCC 3.2 et GCC 3.2.3, regardez combien de bogues ont été corrigés: http://gcc.gnu.org/gcc-3.2/changes.html

Pour d'autres, comme Visual C ++, je ne veux même pas commencer.

Comment faites-vous des compilateurs fiables? Eh bien pour commencer, ils ont des charges et des charges de tests unitaires. Et la planète entière les utilise donc pas de pénurie de testeurs.

Sérieusement, les concepteurs de compilateur que j’aime croire sont des programmeurs de haut niveau et, bien qu’ils ne soient pas infaillibles, ils sont très efficaces.

Fanatic23
la source
19

J'ai rencontré deux ou trois dans ma journée. Le seul moyen de le détecter consiste à consulter le code de l'ensemble.

Bien que les compilateurs soient très fiables pour les raisons indiquées par d'autres affiches, je pense que la fiabilité des compilateurs est souvent une évaluation auto-réalisatrice. Les programmeurs ont tendance à considérer le compilateur comme la norme. Lorsque quelque chose ne va pas, vous assumez que c'est votre faute (parce que c'est 99,999% du temps) et vous modifiez votre code pour résoudre le problème du compilateur plutôt que l'inverse. Par exemple, le crash de code sous un paramètre d'optimisation élevé est sans aucun doute un bogue du compilateur, mais la plupart des gens le règlent un peu plus bas et passent à autre chose sans signaler le bogue.

Karl Bielefeldt
la source
6
+1 pour "afficher le compilateur en tant que norme". J'ai longtemps soutenu qu'il y a deux choses qui définissent vraiment un langage: le compilateur et la bibliothèque standard. Un document de normes n'est qu'une documentation.
Mason Wheeler
8
@Mason: Cela fonctionne bien pour les langues avec une implémentation. Pour les langues nombreuses, le standard est vital. L'impact réel est que, si vous vous plaignez de quelque chose, le fournisseur vous prendra au sérieux s'il s'agit d'un problème de normes et vous dissuadera s'il s'agit d'un comportement non défini ou quelque chose du genre.
David Thornley
2
@Mason - C'est seulement parce que si peu de langues ont un standard et / ou elles sont respectées. Cela, d'ailleurs, à mon humble avis, n'est pas une bonne chose - pour tout type de développement sérieux, on s'attend à ce qu'il dure plus d'une génération de systèmes d'exploitation.
Rook
1
@ David: Ou plus précisément, une implémentation dominante . Borland définit Pascal et Microsoft définit C # indépendamment de ce que disent ANSI et ECMA.
dan04
4
Un blocage de code C, C ++ ou Fortran avec une optimisation élevée est beaucoup plus souvent un code de saisie erroné que des bogues du compilateur. Je travaille très souvent avec des compilateurs récents et des versions préliminaires, souvent pour du matériel très nouveau, et je vois assez régulièrement les échecs liés à l'optimisation. Parce que ces langages ont des notions de comportement indéfini et ne spécifient pas le traitement des programmes non conformes, il faut donc vérifier les plantages assez soigneusement, éventuellement contre l’assemblage. Dans 80 à 90% des cas, le code de l'application est incorrect et non le compilateur.
Phil Miller
14

Les compilateurs ont plusieurs propriétés qui conduisent à leur exactitude:

  • Le domaine est très connu et étudié. Le problème est bien défini et les solutions proposées sont bien définies.
  • Les tests automatisés sont suffisants pour prouver que les compilateurs fonctionnent correctement
  • Les compilateurs ont des tests unitaires très complets, généralement publics et automatisés, qui se sont accumulés au fil du temps pour couvrir davantage d'espace d'erreur que pour la plupart des autres programmes.
  • Les compilateurs ont un très grand nombre de globes oculaires qui regardent leurs résultats
les bleuets
la source
2
En outre, dans de nombreux cas, le code est ancien, GCC a bien plus de 20 ans, comme beaucoup d'autres, de sorte qu'un grand nombre de bugs ont été résolus sur une longue période.
Zachary K
13

Nous utilisons quotidiennement des compilateurs

... et comment rendent-ils les compilateurs si fiables?

Ils ne le font pas. Nous faisons. Parce que tout le monde les utilise tout le temps, les bugs se trouvent rapidement.

C'est un jeu de nombres. Étant donné que les compilateurs sont utilisés de manière omniprésente, il est fort probable que tout bogue sera provoqué par quelqu'un, mais étant donné le nombre élevé d'utilisateurs, il est très peu probable que quelqu'un vous soit spécifiquement.

Cela dépend donc de votre point de vue: les compilateurs sont bogués pour tous les utilisateurs. Mais il est très probable que quelqu'un d' autre aura compilé un morceau similaire de code avant que vous avez fait, si leur était un bug, il aurait les frapper, pas vous, donc de votre personne point de vue, il semble que le bug était jamais là.

Bien entendu, vous pouvez ajouter toutes les autres réponses ici: les compilateurs sont bien documentés, bien compris. Il y a ce mythe selon lequel ils sont difficiles à écrire, ce qui signifie que seuls les très bons et très bons programmeurs tentent réellement d'en écrire un, et font très attention quand ils le font. Ils sont généralement faciles à tester et faciles à tester ou à tester. Les utilisateurs de compilateur ont tendance à être eux-mêmes des programmeurs experts, ce qui conduit à des rapports de bogue de haute qualité. Et l’inverse: les auteurs de compilateur ont tendance à utiliser leur propre compilateur.

Jörg W Mittag
la source
11

En plus de toutes les réponses déjà, j'aimerais ajouter:

Je crois souvent que les vendeurs mangent leur propre nourriture pour chiens. Cela signifie qu'ils écrivent les compilateurs eux-mêmes.

DevSolo
la source
7

J'ai souvent rencontré des bogues de compilation.

Vous pouvez les trouver dans les coins les plus sombres où il y a moins de testeurs. Par exemple, pour trouver des bogues dans GCC, vous devriez essayer:

  • Construire un compilateur croisé. Vous trouverez littéralement des dizaines de bogues dans les scripts de configuration et de construction de GCC. Certains aboutissent à des échecs de construction lors de la compilation de GCC et d'autres à l'échec du compilateur croisé pour générer des exécutables fonctionnels.
  • Construisez une version Itanium de GCC en utilisant profile-bootstrap. Les dernières fois où j'ai essayé ceci sur GCC 4.4 et 4.5, il n'a pas réussi à produire un gestionnaire d'exceptions C ++ fonctionnel. La construction non optimisée a bien fonctionné. Personne n'a semblé intéressé à réparer le bogue que j'ai signalé et j'ai arrêté de le réparer moi-même après avoir essayé de fouiller dans les spécifications de mémoire de GCC asm.
  • Essayez de créer votre propre fichier GCJ à partir des dernières nouveautés sans suivre de script de construction de la distribution. Je te défie.
Zan Lynx
la source
Nous trouvons beaucoup de problèmes avec IA64 (Itanium). Nous n'avons pas beaucoup de clients pour cette plate-forme, nous avons donc l'habitude de corriger le niveau d'optimisation. Cela nous ramène aux autres réponses. Les compilateurs de langages populaires d'architectures populaires ont généralement bénéficié d'une exposition suffisante de la part des utilisateurs et d'un support suffisant pour être assez bon.
Omega Centauri
@ Omega: Réduire l'optimisation semble être ce que tout le monde fait. Malheureusement, Itanium nécessite des compilateurs hautement optimaux pour fonctionner correctement. Oh bien ...
Zan Lynx
Je t'entends. Franchement, l’architecture était déjà obsolète lorsqu’elle est sortie, heureusement, AMD a forcé Intels à prendre la main sur x86-64 (ce qui malgré ses nombreuses verrues n’est pas si grave). Si vous parvenez à décomposer vos fichiers source, vous pourrez peut-être isoler le problème et trouver une solution de contournement. C’est ce que nous faisons s’il s’agit d’une plate-forme importante, mais pas pour IA64.
Omega Centauri
@ Omega: Malheureusement, j'aime vraiment beaucoup Itanium. C'est une architecture merveilleuse. Je considère que les x86 et x86-64 sont obsolètes mais, bien sûr, ils ne mourront jamais.
Zan Lynx
Le x86 est un peu bizarre. Ils continuent à y ajouter de nouvelles choses, de sorte qu'il se développe une verrue à la fois. Mais le moteur d’exécution hors service fonctionne plutôt bien et le nouveau système SSE => AVX offre de réelles possibilités à ceux qui souhaitent le coder. Certes, de nombreux transistors sont dédiés à la fabrication de matériel semi-obsolète, mais c’est un prix que l’on paye pour la compatibilité héritée.
Omega Centauri
5

Plusieurs raisons:

  • Les auteurs du compilateur " mangent leur propre nourriture pour chien ".
  • Les compilateurs sont basés sur des principes bien compris de la CS.
  • Les compilateurs sont construits selon des spécifications très claires .
  • Les compilateurs sont testés .
  • Les compilateurs ne sont pas toujours très fiables .
Kramii réintègre Monica
la source
4

Ils sont généralement très bons à -O0. En fait, si nous suspectons un bogue du compilateur, nous comparons -O0 au niveau que nous essayons d'utiliser. Des niveaux d'optimisation plus élevés comportent un risque plus élevé. Certains le sont même délibérément, et étiquetés comme tels dans la documentation. J'en ai rencontré beaucoup (au moins une centaine à mon époque), mais ces dernières sont de plus en plus rares. Néanmoins, à la recherche de bons numéros de point de repère (ou d’autres références importantes pour le marketing), la tentation de repousser les limites est grande. Il y a quelques années, nous avons eu des problèmes lorsqu'un fournisseur (pour rester anonyme) a décidé de violer la parenthèse par défaut, plutôt qu'une option de compilation spéciale clairement identifiée.

Il peut être difficile de diagnostiquer une erreur du compilateur par opposition à une référence de mémoire parasite, une recompilation avec différentes options peut simplement brouiller le positionnement relatif des objets de données dans la mémoire, de sorte que vous ne savez pas s'il s'agit de Heisenbug de votre code source ou d'un buggy. compilateur. De plus, de nombreuses optimisations apportent des modifications légitimes à l'ordre des opérations, voire des simplifications algébriques à votre algèbre. Celles-ci auront des propriétés différentes en ce qui concerne l'arrondi en virgule flottante et les dépassements inférieurs / supérieurs. Il est difficile de distinguer ces effets des vrais bugs. C'est pour cette raison que l'informatique en virgule flottante est difficile, car les bugs et la sensibilité numérique ne sont souvent pas faciles à démêler.

Omega Centauri
la source
4

Les bogues du compilateur ne sont pas si rares. Le cas le plus courant est qu'un compilateur signale une erreur sur un code devant être accepté ou un compilateur accepte un code qui aurait dû être rejeté.

Kevin Cline
la source
Malheureusement, nous ne voyons pas la deuxième classe de bugs: le code compile = tout va bien. Donc probablement la moitié des bogues (en supposant un ratio de 50-50 entre les deux classes de bogues) ne sont pas trouvés par des personnes, mais par les tests unitaires du compilateur
Gianluca Ghettini
3

Oui, j'ai rencontré un bogue dans le compilateur ASP.NET hier:

Lorsque vous utilisez des modèles fortement typés dans les vues, le nombre de paramètres que les modèles peuvent contenir est limité. Évidemment, il ne peut prendre plus de 4 paramètres de modèle, de sorte que les deux exemples ci-dessous rendent le compilateur trop difficile à gérer:

ViewUserControl<System.Tuple<type1, type2, type3, type4, type5>>

Ne compilerait pas tel quel, mais sera si type5est supprimé.

ViewUserControl<System.Tuple<MyModel, System.Func<type1, type2, type3, type4>>>

Compilerait si type4est supprimé.

Notez que cela System.Tuplea beaucoup de surcharges et peut prendre jusqu'à 16 paramètres (c'est fou je sais).

utilisateur8685
la source
3

Avez-vous déjà rencontré un bogue dans le compilateur lui-même? Qu'est-ce que c'était et comment avez-vous réalisé que le problème était dans le compilateur lui-même?

Ouaip!

Les deux plus mémorables sont les deux premiers que j'ai rencontrés. Ils étaient tous deux dans le compilateur Lightspeed C pour 680x0 Macs vers 1985-7.

La première concernait les cas où, dans certaines circonstances, l'opérateur de postincrément entier ne faisait rien - autrement dit, dans un morceau de code particulier, "i ++" ne faisait tout simplement rien pour "i". Je tirais mes cheveux jusqu'à ce que je regarde un démontage. Ensuite, j'ai simplement incrémenté différemment et soumis un rapport de bogue.

La seconde était un peu plus compliquée, et était une "fonctionnalité" mal réfléchie qui a mal tourné. Les premiers Mac avaient un système compliqué pour effectuer des opérations de disque de bas niveau. Pour une raison quelconque, je n'ai jamais compris - probablement en rapport avec la création d'exécutables plus petits - plutôt que le compilateur générant simplement les instructions d'opération de disque sur place dans le code d'objet, le compilateur Lightspeed appelle une fonction interne qui, au moment de l'exécution, génère l'opération de disque. instructions sur la pile et y ont sauté.

Cela fonctionnait très bien sur 68000 processeurs, mais lorsque vous exécutiez le même code sur un processeur 68020, il faisait souvent des choses étranges. Il s'est avéré qu'une nouvelle fonctionnalité du 68020 était un cache d'instruction d'instruction primitive de 256 octets. Étant donné que nous étions à l’origine des caches de CPU, il n’avait aucune idée que le cache était "sale" et devait être rempli; Je suppose que les concepteurs de CPU chez Motorola n’ont pas pensé au code à modification automatique. Par conséquent, si vous exécutez deux opérations sur le disque assez proches dans votre séquence d'exécution et que le moteur d'exécution Lightspeed construit les instructions au même endroit sur la pile, le CPU pense à tort qu'il a un cache d'instruction et exécute la première opération de disque deux fois.

Encore une fois, comprendre cela a pris un peu de temps à creuser avec un désassembleur et beaucoup de démarches simples dans un débogueur de bas niveau. Ma solution de contournement consistait à préfixer chaque opération de disque par un appel à une fonction exécutant 256 instructions "NOP", qui inondaient (et donc effaçaient) le cache d'instructions.

Au cours des 25 années qui se sont écoulées depuis, j'ai vu de moins en moins de bogues de compilateur au fil du temps. Je pense qu'il y a plusieurs raisons à cela:

  • Il y a un nombre croissant de tests de validation pour les compilateurs.
  • Les compilateurs modernes sont généralement divisés en deux parties ou plus, l'une générant du code indépendant de la plate-forme (par exemple, les LLVM ciblant ce que vous pourriez considérer comme un processeur imaginaire), et une autre traduisant cela en instructions pour votre matériel cible réel. Dans les compilateurs multi-plateformes, la première partie est utilisée partout, ce qui permet de réaliser des tonnes de tests dans le monde réel.
Bob Murphy
la source
Une des raisons pour éviter le code auto-modifiant.
Technophile
3

Trouvé une erreur flagrante dans Turbo Pascal il y a 5,5 ans. Une erreur ne figure ni dans la version précédente (5.0) ni dans la version suivante (6.0) du compilateur. Et un test qui aurait dû être facile à tester, car ce n’était pas du tout une majuscule (juste un appel qui n’est pas aussi courant).

En général, les constructeurs de compilateurs commerciaux (plutôt que les projets de loisir) disposeront de procédures d’assurance qualité et de tests très complètes. Ils savent que leurs compilateurs sont leurs projets phares et que leurs failles leur seront très mauvaises, pire qu’ils ne le feraient d’autres sociétés qui fabriquent la plupart des autres produits. Les développeurs de logiciels sont un groupe impitoyable. Nos fournisseurs d’outils nous ont laissé savoir que nous allions probablement chercher des solutions de rechange plutôt que d’attendre une solution de leur fournisseur. Nous sommes très susceptibles de le communiquer à nos pairs qui pourraient bien suivre notre exemple. Dans de nombreux autres secteurs, ce n'est pas le cas. Par conséquent, la perte potentielle pour un fabricant de compilateur à la suite d'un grave bogue est bien supérieure à celle d'un fabricant de logiciels de montage vidéo.

jwenting
la source
2

Lorsque le comportement de votre logiciel est différent lors de la compilation avec -O0 et avec -O2, vous avez détecté un bogue du compilateur.

Lorsque le comportement de votre logiciel diffère de vos attentes, il est probable que le bogue se trouve dans votre code.

mouviciel
la source
8
Pas nécessairement. En C et C ++, il existe une quantité agaçante de comportements indéfinis et indéterminés, qui peuvent légitimement varier en fonction du niveau ou de la phase d'optimisation de la lune ou du mouvement des indices de Dow Jones. Ce test fonctionne dans des langues plus étroitement définies.
David Thornley
2

Les bogues du compilateur se produisent, mais vous avez tendance à les trouver dans des coins étranges ...

Il y avait un bug étrange dans le compilateur VAX VMS C de Digital Equipment Corporation dans les années 1990

(Je portais un oignon à la ceinture, comme c'était la mode à l'époque)

Un point-virgule supplémentaire précédant n'importe quelle boucle for serait compilé en tant que corps de la boucle for.

f(){...}
;
g(){...}

void test(){
  int i;
  for ( i=0; i < 10; i++){
     puts("hello");
  }
}

Sur le compilateur en question, la boucle ne s'exécute qu'une fois.

il voit

f(){...}
g(){...}

void test(){
  int i;
  for ( i=0; i < 10; i++) ;  /* empty statement for fun */

  {
     puts("hello");
  }
}

Cela m'a coûté beaucoup de temps.

L'ancienne version du compilateur PIC C que nous avions l'habitude d'infliger à l'expérience de travail, nous ne pouvions pas générer de code utilisant correctement l'interruption de priorité élevée. Vous avez dû attendre 2-3 ans et mettre à niveau.

Le compilateur MSVC 6 avait un bogue astucieux dans l’éditeur de liens, il commettrait une erreur de segmentation et mourrait de temps à autre sans raison. Une construction propre l'a généralement réparée (mais ne soupire pas toujours).

Tim Williscroft
la source
2

Dans certains domaines, tels que le logiciel avionique, les exigences en matière de certification sont extrêmement élevées, tant pour le code et le matériel que pour le compilateur. À propos de cette dernière partie, il existe un projet visant à créer un compilateur C formellement vérifié, appelé Compcert . En théorie, ce type de compilateur est aussi fiable qu’il se présente.

Axel
la source
1

J'ai vu plusieurs bogues du compilateur, j'en ai signalé quelques-uns (plus précisément en F #).

Cela dit, je pense que les bogues du compilateur sont rares car ceux qui écrivent des compilateurs sont généralement très à l'aise avec les concepts rigoureux de l'informatique qui les rendent vraiment conscients des implications mathématiques du code.

La plupart d'entre eux sont probablement très familiers avec des choses comme le calcul lambda, la vérification formelle, la sémantique dénotationnelle, etc., des choses qu'un programmeur moyen comme moi peut à peine comprendre.

En outre, il existe généralement un mappage assez simple entre entrée et sortie dans les compilateurs. Par conséquent, le débogage d'un langage de programmation est probablement beaucoup plus facile que le débogage, par exemple, d'un moteur de blog.

Rei Miyasaka
la source
1

J'ai trouvé un bogue dans le compilateur C # pas trop longtemps, vous pouvez voir comment Eric Lippert (qui est sur l'équipe de conception C #) a compris ce que le bug était ici .

En plus des réponses déjà données, j'aimerais ajouter quelques éléments supplémentaires. Les concepteurs de compilateurs sont souvent de très bons programmeurs. Les compilateurs sont très importants: la plupart des programmes sont réalisés à l'aide de compilateurs, il est donc impératif que le compilateur soit de haute qualité. Les entreprises qui fabriquent des compilateurs ont donc tout intérêt à y mettre leurs meilleurs collaborateurs (ou du moins de très bons: les meilleurs n’aiment peut-être pas la conception de compilateurs). Microsoft aimerait beaucoup que leurs compilateurs C et C ++ fonctionnent correctement, sinon le reste de la société ne peut pas faire son travail.

En outre, si vous construisez un compilateur très complexe, vous ne pouvez pas le pirater ensemble. La logique derrière les compilateurs est à la fois très complexe et facile à formaliser. Par conséquent, ces programmes seront souvent construits de manière très «robuste» et générique, ce qui tend à réduire le nombre de bogues.

Alex ten Brink
la source