Le C est l'un des langages de programmation les plus populaires au monde ; il a été initialement développé par Dennis Ritchie entre 1969 et 1973 aux AT&T Bell Labs. Des milliers de projets ont été développés en C depuis lors. Il est utilisé pour toutes sortes d'applications : systèmes d'exploitation, applications embarquées, développement de jeux, traitement d'images, traitement de texte et moteurs de bases de données.
Presque tous les autres langages ont considérablement évolué au fil des ans, mais ce n'est pas vraiment le cas du C ; par exemple, la norme C11 n'a pas apporté beaucoup de nouvelles fonctionnalités au C — seules quelques modifications ont été introduites.
Qu'est-ce qui rend le langage C si populaire, même 50 ans après sa création ?
I- La stabilité du langage
Retour en 1990 : les débuts de Microsoft Word
Les développeurs de cette époque se souviennent d'un temps où un ordinateur personnel typique pouvait avoir un processeur à 8 MHz, 1 mégaoctet de mémoire, un disque dur de 20 mégaoctets et un lecteur de disquettes. Développer une application de traitement de texte était un grand défi.
Microsoft a récemment publié le code source de « Microsoft Word 1.1 » au Computer History Museum. Son code source vaut vraiment la peine d'être exploré ; même s'il a été écrit il y a 25 ans, on peut encore en tirer des techniques très intéressantes.
Voici un extrait de son code source :

Comme on peut le constater, la fonction a été déclarée dans le style K&R. Toutes les fonctions utilisent le même style.
En explorant les fichiers sources de « Microsoft Word 1.1 », une observation intéressante est que les techniques utilisées dans les projets récents ne diffèrent pas beaucoup de celles utilisées dans l'implémentation de « Microsoft Word 1.1 ».
Prenons le code source suivant comme exemple :

On dirait que ce code provient d'un projet C créé récemment sur GitHub. Rien n'indique qu'il s'agit de code vieux de 25 ans.
1994, l'année de la première version de Linux
Le 14 mars 1994, Linux 1.0.0 est sorti, mais le développement a commencé en 1991, grâce à Linus Torvalds et à tous les autres contributeurs. Le code source de cette première version est disponible ici.
Voici un extrait du fichier source sched.c :

En explorant les fichiers sources du noyau Linux version 1 et de toutes les versions les plus récentes, une observation surprenante est à quel point ils se ressemblent — sans changement majeur de style ni dans les techniques utilisées. Dès le début, le code était simple, propre et basique.
II- Des mécanismes basiques
Modularité
La modularité est une technique de conception logicielle qui consiste à composer un logiciel à partir de parties distinctes ; le code modulaire est généralement plus facile à gérer et à maintenir.
Pour un langage procédural comme le C, où les artefacts logiques comme les espaces de noms, les composants ou les classes n'existent pas, nous pouvons modulariser en utilisant des répertoires et des fichiers.
Voici quelques scénarios possibles :
- Placez tous les fichiers sources dans un seul répertoire.
- Isoler les fichiers liés à un module ou sous-module dans un répertoire spécifique.
Par exemple, dans le cas du noyau Linux, des répertoires et sous-répertoires sont utilisés pour modulariser le code source du noyau.

Encapsulation
L'encapsulation consiste à masquer les fonctions et les données internes à une implémentation. En C, l'encapsulation s'effectue à l'aide du mot-clé static. Ces entités sont appelées fonctions et variables à portée de fichier.
Recherchons toutes les fonctions statiques en exécutant la requête CQLinq suivante.

Nous pouvons utiliser la vue métrique pour avoir une bonne idée du nombre de fonctions concernées. Dans la vue Metric, la base de code est représentée par un treemap. Le treemapping est une méthode d'affichage de données arborescentes à l'aide de rectangles imbriqués. L'arborescence utilisée dans un treemap CppDepend est la hiérarchie de code habituelle :
- Les projets contiennent des répertoires.
- Les répertoires contiennent des fichiers.
- Les fichiers contiennent des structs, des fonctions et des variables.
La vue treemap offre un moyen pratique de représenter le résultat d'une requête CQLinq, afin de voir visuellement les types concernés par la requête.

Comme on peut le constater, de nombreuses fonctions sont déclarées static.
Recherchons maintenant les champs statiques :

La même observation s'applique aux fonctions : de nombreuses variables sont déclarées static.
Dans le code source du noyau Linux, l'encapsulation est utilisée chaque fois que des fonctions et des variables doivent rester privées à la portée du fichier.
Conclusion
Après ce bref retour en arrière sur quelques anciens projets C, nous pouvons constater que très peu de techniques d'implémentation ont changé par rapport aux projets C modernes.
L'une des forces du C est sa stabilité au fil des ans : il reste un langage relativement simple, peu de mécanismes avancés ont été introduits, et son code reste simple à comprendre et à maintenir.
