C
Aux Bell Labs, au début des années 1970, l’ambiance n’était pas à l’optimisme. L’entreprise venait de claquer la porte de Multics, ce projet pharaonique mené avec le MIT et General Electric qui avait englouti des budgets considérables sans tenir ses promesses. Déçu, Ken Thompson décida de prendre les choses en main pour créer son propre environnement informatique, selon sa vision personnelle.
Il récupéra un vieux DEC PDP-7, une machine déjà dépassée avec ses maigres 8 Ko de mémoire. Là-dessus, il bâtit les premières versions d’UNIX, d’abord en assembleur. Mais programmer directement en assembleur, c’était l’enfer quotidien. Thompson avait testé Fortran, sans succès. Il créa B, une version allégée de BCPL qui tenait dans les contraintes de mémoire du PDP-7.
Dennis Ritchie arriva dans l’équipe et constata que B montrait ses limites. Entre 1969 et 1973, il entreprit de le faire muer vers quelque chose de plus ambitieux. 1972 fut l’année décisive. Le passage au PDP-11 révéla les faiblesses de B : sa gestion des caractères posait problème, et ses pointeurs généraient des conversions absurdes entre indices de mots et adresses. B ignorait complètement les nombres à virgule flottante, alors que le PDP-11 allait bientôt savoir les manipuler.
Ritchie introduisit d’abord les types avec « New B », ajoutant int et char avec leurs tableaux et pointeurs. Mais c’est avec C que l’idée prit vraiment forme. Le système de types devint sophistiqué, autorisant la composition de structures complexes à partir des types de base. Ritchie eut une intuition géniale pour la syntaxe des déclarations : faire en sorte qu’elle reflète l’usage. Si vous écrivez int *p, c’est parce que *p vous donne un int.
La gestion des tableaux causa des débats. En C, le nom d’un tableau se transforme automatiquement en pointeur vers son premier élément dans les expressions. Cette approche résolvait élégamment le problème des chaînes de caractères tout en préservant le code B existant. Le préprocesseur arriva en 1972-1973, modeste au départ avec juste l’inclusion de fichiers et quelques macros.
En 1973, C était mûr. Ritchie et Thompson s’attaquèrent à la réécriture complète du noyau UNIX. Pari audacieux : personne n’avait encore prouvé qu’un langage de haut niveau pouvait produire du code assez rapide pour un système d’exploitation. Le pari fut gagné. Entre 1973 et 1980, C continua sa croissance : types unsigned et long, union, énumérations, structures devenues citoyens de première classe.
Brian Kernighan et Dennis Ritchie publièrent The C Programming Language en 1978. Ce petit livre blanc, que tout le monde appelait « K&R », devint la bible du langage. Sa clarté remarquable contribua largement à populariser C. Mais le langage manquait d’une norme officielle, et chaque compilateur apportait ses petites variations.
La standardisation s’imposa au début des années 1980. C débordait d’UNIX et colonisait d’autres systèmes. Le comité ANSI X3J11 se forma en 1983 sous l’impulsion de M. D. McIlroy. Fin 1989, la norme ANSI C était prête, adoptée comme standard international ISO/IEC 9899-1990. Le comité resta prudent, n’introduisant qu’une modification majeure : l’intégration des types d’arguments dans les signatures de fonctions. Cette idée, empruntée à C++, renforçait le contrôle de types sans casser l’existant.
L’expansion de C fut fulgurante. Dans les années 1980, des compilateurs apparurent sur pratiquement toutes les architectures et tous les systèmes. Les développeurs de logiciels commerciaux pour micro-ordinateurs l’adoptèrent massivement. Cette réussite tenait à l’équilibre du langage : assez simple pour être maîtrisé, assez proche de la machine pour produire du code efficace, assez abstrait pour la portabilité.
C engendra une descendance prolifique. Bjarne Stroustrup créa C++, et d’autres donnèrent naissance à Objective C et Concurrent C. Par la suite, les langages modernes qui ont repris sa syntaxe et ses concepts sont innombrables. Les pointeurs, le traitement des tableaux, la syntaxe des déclarations de types restent des contributions durables, même si elles font débat.
Le langage a ses défauts. La modularisation des gros systèmes demeure problématique avec sa structure de nommage à deux niveaux seulement. La gestion manuelle de la mémoire dynamique piège régulièrement les programmeurs. Ces faiblesses n’ont pourtant pas empêché le développement de systèmes d’exploitation complets en C.
L’histoire de C montre comment un outil né de nécessités pratiques immédiates devient, par des choix de conception judicieux, un standard qui traverse les époques. Sa longévité dans un univers technologique en perpétuel bouleversement témoigne de la justesse des intuitions de ses créateurs. Plus de cinquante ans après sa naissance, C figure encore parmi les langages les plus utilisés dans la programmation système et embarquée. Go, dont Ken Thompson est le co-créateur, tente de le rattraper.