Compiler n’est pas jouer

C'est bien connu, les ordinateurs ne manipulent que des 0 et des 1. Difficile cependant de se contenter de ce paysage binaire : programmer uniquement avec des 0 et des 1 serait vite inhumain. L'informatique a donc inventé une multitude de façons de rendre les données plus intelligibles. Pourquoi autant de méthodes ? Parce que la question est tout sauf simple - comme souvent dès qu'il s'agit de compilation, c'est-à-dire de traduire un langage humainement lisible en instructions exécutables par la machine. Derrière cette opération technique se cachent des choix profondément humains, qui alimentent d'ailleurs des débats passionnés entre spécialistes.

Les langages sont innombrables, et leur conception répond toujours à un contexte précis. Une même suite de 0 et de 1 peut désigner un gif amusant, une photo de famille, une transaction bancaire, un bilan sanguin ou le régime d'un réacteur d'avion en plein vol. Sous l'uniformité du binaire se dissimulent donc des contraintes très différentes. Les simulations météorologiques, qui brassent des volumes immenses de données, nécessitent des programmes extrêmement rapides, écrits au plus près de la machine - de bas niveau. Le pilotage d'une fusée réclame, lui, des calculs strictement garantis, sans approximations hasardeuses. Et les gifs rigolos ? Ils appellent des outils de programmation simples et accessibles : plus on est de fous, plus on rit.

Or ces contraintes, déjà difficiles à satisfaire isolément, le deviennent davantage encore lorsqu'il faut les concilier. Les concepteurs de compilateurs doivent donc faire des choix : la mémoire est-elle laissée à la main du programmeur, ou prise en charge automatiquement ? La syntaxe doit-elle être impitoyable au moindre symbole oublié, ou suffisamment souple pour accepter le plus de programmes possibles ? Et surtout, faut-il traiter les données comme une simple masse de bits, ou leur donner un sens ?

Donner un sens aux données, c'est introduire ce que les informaticiens appellent des types. Le typage consiste à associer aux variables une nature intelligible : nombres entiers ou réels, textes et structures complexes - arbres, graphes, images. Dans un langage typé, le système de types propose un modèle abstrait de ce que l'on manipule : telle suite de bits représente un réel, telle autre un réel borné entre 0 et 1, ceci une longueur en mètres, cela une durée en secondes. Ces distinctions structurent le programme dès son écriture et guident sa compilation. Le typage relève ainsi d'un niveau d'abstraction élevé, éloigné de la mécanique brute de la machine et propice au raisonnement et à la formalisation des algorithmes.

Ce choix oriente les techniques de compilation. Certains types occupent plus d'espace mémoire que d'autres : introduire un typage, c'est fixer la représentation concrète des données et déterminer la taille des zones à allouer, ce qui permet de mieux encadrer la gestion de la mémoire. Or les erreurs dans ce domaine - accès hors limites, utilisation d'une zone déjà libérée - figurent parmi les sources de vulnérabilité les plus courantes. En 2022, Google indiquait que près de 70 % des failles de sécurité de Chrome étaient liées à des problèmes de gestion mémoire (1).

Le type d'une variable détermine aussi les opérations autorisées. Multiplier 5 par 37 a un sens : ce sont deux nombres entiers. Multiplier Les Misérables par Mémoires d'Hadrien en a beaucoup moins. Et multiplier un entier par un réel ? Tout dépend du niveau d'exigence. Les nombres réels introduisent des erreurs d'arrondi que les entiers évitent. Si ces approximations sont acceptables, l'opération est permise. Mais les langages dits fortement typés, comme OCaml, adoptent la prudence : ils interdisent par défaut le mélange des types, car le résultat ne serait plus garanti exact. Les calculs restent évidemment possibles, mais c'est au programmeur d'en prendre la responsabilité, en indiquant explicitement qu'il veut transformer, par exemple, l'entier en réel. Ces compilateurs rejettent donc plus facilement les programmes. Une discipline que l'on peut trouver pesante... ou rassurante, selon que l'on écrit le code ou qu'on embarque dans l'avion dont ils pilotent les commandes.

Depuis quelques années, le typage s'est imposé comme un véritable outil d'ingénierie logicielle. Cette évolution est portée par les grandes entreprises du numérique, qui maintiennent des bases de code gigantesques, écrites par des centaines d'ingénieurs et actualisées pendant des décennies. Avec le temps, ces systèmes deviennent si complexes que la moindre retouche - parfois une simple clarification - peut provoquer des catastrophes en cascade.

LE LANGAGE RUST : UNE ALLIANCE INATTENDUE ENTRE PUISSANCE ET SÛRETÉ

Dans ce contexte, un système de types robuste permet de structurer le code, de repérer les incohérences avant même l'exécution et de sécuriser les évolutions futures. C'est ainsi que Microsoft a lancé en 2012 TypeScript, ajoutant un typage à JavaScript, pilier du Web mais historiquement très permissif. Facebook a suivi une démarche comparable avec PHP, avant de développer son propre langage typé, Hack, pour mieux maîtriser ses infrastructures. Comme le résume Gabriel Radanne, spécialiste de compilation à l'Inria à Lyon, l'enjeu est double : améliorer le confort des programmeurs - en rendant les erreurs plus visibles et les intentions plus explicites - et optimiser les performances. "Plus on a de bons types, plus c'est facile d'optimiser", souligne-t-il.

Au fil des discussions sur le typage, un nom s'impose aujourd'hui : Rust. Né en 2006 comme projet personnel d'un ingénieur de Mozilla, ce langage a depuis connu une ascension spectaculaire, jusqu'à être adopté par des acteurs comme Amazon, Google, Meta et Discord. À l'origine, Rust devait contribuer au moteur de rendu du navigateur Firefox, avec une priorité claire : l'efficacité. Fait révélateur, son premier compilateur était écrit en OCaml, langage de haut niveau réputé pour la sophistication de son système de types. Le langage Rust incarne un compromis ambitieux entre deux traditions souvent opposées. Il permet de programmer au plus près de la machine, à la manière de C ou C++, tout en s'appuyant sur un système de types riche et expressif. On peut ainsi inscrire dans le type qu'une donnée - un nombre réel, par exemple - ne peut être modifiée que par une portion précise du code. Autrement dit, Rust tente de concilier performance bas niveau et garanties formelles, en intégrant dans les types des règles autrefois laissées à la seule vigilance du programmeur. Une alliance inattendue entre puissance et sûreté. "Rust attire une communauté plutôt haut niveau, mais en quête de performances, et il commence à séduire des milieux historiquement focalisés sur l'efficacité, comme le calcul intensif, les moteurs de rendu de jeux vidéo ou la bio-informatique", observe Gabriel Radanne.

Cette ambition ne sort pas de nulle part. Rust s'inscrit notamment dans le sillage du projet académique Cyclone, né au début des années 2000, qui explorait déjà l'idée d'un typage explicite pour garantir la sûreté de la mémoire sans sacrifier l'efficacité. Son principal défaut reste sa difficulté d'apprentissage : la rigueur qu'il impose peut dérouter. D'où les efforts importants consacrés aujourd'hui à la pédagogie et à l'amélioration des outils, condition indispensable à sa diffusion. "Le compilateur Rust a les meilleurs messages d'erreur que je connaisse", ajoute Gabriel Radanne. Fournir de bons messages d'erreur, c'est un cadeau au programmeur : plus le message est précis, plus il est facile de trouver, donc de corriger l'erreur. Or le typage aide à préciser les messages. Alors que les choix de compilation passionnent et divisent, le typage adoucirait-il les mœurs ?

(1) tinyurl.com/failles-securite-chrome

Charlotte Truchet est professeure en informatique à Sorbonne Université. Elle dirige le laboratoire Science et technologie de la musique et du son à l'Ircam.

Bloc en kiosque

Mobile : L'application mobile