C est le meilleur choix (2025)
(sqlite.org)- Depuis 2000, SQLite est un moteur de base de données léger implémenté en C, et il n’est pas prévu de le réécrire dans un autre langage
- C est considéré comme le langage le plus adapté à SQLite du point de vue des performances, de la compatibilité, de la faible dépendance et de la stabilité
- Les langages orientés objet (C++, Java, etc.) présentent de fortes contraintes d’appel interlangage, et une approche procédurale peut au contraire être plus simple et plus rapide
- Les « langages sûrs » comme Rust ou Go ne sont pas encore assez matures et ne correspondent pas à la stratégie qualité de SQLite (par ex. tests de branches à 100 %, récupération en cas de OOM)
- Un portage futur vers Rust reste envisageable, mais seulement si plusieurs conditions sont remplies en matière de maturité, de compatibilité, de performances et de support des outils
1. Pourquoi C est le meilleur choix
- SQLite a été implémenté dès le départ en C standard le 29 mai 2000, et il n’existe toujours aucun projet de migration vers un autre langage
- Les raisons avancées en faveur de C pour implémenter SQLite sont les performances, la compatibilité, la faible dépendance et la stabilité
1.1 Performances
- SQLite est une bibliothèque bas niveau utilisée de façon intensive, où la rapidité est indispensable
- Les documents “Internal Versus External BLOBs” et “35% Faster Than The Filesystem” sont cités comme preuves de performance
- C fournit un contrôle proche du matériel au point d’être qualifié de « langage assembleur portable », tout en conservant la portabilité entre plateformes
- D’autres langages affirment être « aussi rapides que C », mais aucun ne prétend être plus rapide que C
1.2 Compatibilité
- Presque tous les systèmes permettent d’appeler des bibliothèques écrites en C
- Par exemple, Android permet à des applications Java d’appeler SQLite via un adaptateur
- Si SQLite avait été écrit en Java, il n’aurait pas pu être utilisé dans des applications iPhone basées sur Objective-C ou Swift
1.3 Faible dépendance
- Les bibliothèques écrites en C ont très peu de dépendances d’exécution
- Dans sa configuration minimale, SQLite n’a besoin que des fonctions suivantes de la bibliothèque C standard
- memcmp(), memcpy(), memmove(), memset(), strcmp(), strlen(), strncmp()
- Même dans une build complète, il n’utilise guère plus que malloc(), free() et les entrées/sorties de fichiers
- À l’inverse, les langages modernes exigent souvent des runtimes de plusieurs Mo et des milliers d’interfaces
1.4 Stabilité
- C est un langage ancien qui évolue peu, offrant un comportement clair et prévisible
- Lorsqu’on développe un moteur de base de données petit, rapide et fiable comme SQLite, il est important que les spécifications du langage ne changent pas fréquemment
2. Pourquoi SQLite n’a pas été écrit dans un langage orienté objet
-
Certains développeurs pensent qu’un système complexe ne peut être implémenté qu’avec un langage orienté objet, mais SQLite montre le contraire
-
Les bibliothèques écrites en C++ ou en Java ne peuvent généralement être utilisées que par des applications écrites dans le même langage
- À l’inverse, une bibliothèque C peut être appelée depuis presque n’importe quel langage
-
L’orientation objet est un modèle de conception, pas le langage lui-même ; il est aussi possible d’implémenter une structure orientée objet en C
-
L’orientation objet n’est pas toujours la meilleure solution, et du code procédural peut être plus simple, plus facile à maintenir et plus performant dans certains cas
-
Aux débuts de SQLite (début des années 2000), Java était encore immature et C++ souffrait de graves problèmes de compatibilité entre compilateurs
- À l’époque, C était clairement un meilleur choix, et il y a encore aujourd’hui très peu d’intérêt à une réécriture
3. Pourquoi SQLite n’est pas écrit dans un « langage sûr »
- Ces dernières années, des « langages sûrs » comme Rust et Go ont attiré l’attention, mais SQLite reste en C
- Pendant les dix premières années de SQLite, les langages sûrs n’existaient pas
- Une réécriture en Go ou en Rust serait possible, mais elle comporterait un risque de nouveaux bugs et de baisse de performance
- Les langages sûrs insèrent souvent des branches supplémentaires comme les vérifications de limites de tableau
- Dans un code correct, ces branches ne sont pas exécutées, ce qui rend impossible d’atteindre 100 % de tests de branches
- La plupart des langages sûrs interrompent le programme en cas de manque de mémoire (OOM)
- SQLite est conçu pour se rétablir correctement même en cas de OOM, ce qui entre en conflit avec ce comportement
- Tous les langages sûrs existants sont récents et évoluent rapidement
- SQLite préfère un langage ancien et stable
4. Possibilité d’un portage vers Rust
- Il existe une possibilité de réécrire SQLite en Rust, mais un portage vers Go est presque impossible
- Raison : Go n’aime pas assert()
- Conditions préalables à un portage vers Rust
- Rust devra gagner en maturité et ralentir son rythme d’évolution pour devenir un “langage ancien et stable”
- Rust devra pouvoir générer des bibliothèques génériques appelables depuis tous les langages
- Il devra générer du code objet pouvant fonctionner sur des appareils embarqués sans système d’exploitation
- Il devra disposer d’un outillage permettant des tests avec 100 % de couverture de branches
- Il devra fournir un mécanisme de récupération en cas de OOM
- Il devra démontrer une implémentation sans perte de performance au niveau de C
- Les développeurs qui pensent que Rust remplit ces conditions peuvent contacter directement l’équipe SQLite pour en discuter
5. Conclusion
- SQLite est un moteur de base de données petit, rapide et fiable, et les caractéristiques du langage C correspondent à cet objectif
- Une transition vers un langage orienté objet ou un langage sûr n’apporterait pas de bénéfice réel en matière de compatibilité, de performances ou de contrôle qualité
- La simplicité et la stabilité de C soutiennent la maintenance à long terme et la fiabilité de SQLite
8 commentaires
De toute façon, c’est un projet qui n’accepte même pas les PR, donc bon… ils utilisent simplement ce qu’ils ont envie d’utiliser.
Dans des contextes contraints, il n’existe pas de langage capable de remplacer C, C++ ou Rust. Il y a simplement peu de développeurs qui comprennent le fait de développer en se préoccupant des dépassements à l’échelle du bit ou du piratage sur des structures ou des
map.Le titre est trop sensationnaliste. Si vous regardez l’article original, vous verrez qu’il explique pourquoi le C est le langage le plus adapté au développement de SQLite. J’espère que tout le monde se calmera.
Non, et même le texte lui-même a été écrit il y a 7 ans, non ? On dirait qu’une partie a été mise à jour en 2025 en ajoutant du contenu ensuite... 🤦
L’important, c’est d’être capable de juger quelle langue convient à différentes situations de développement, pas de prétendre qu’une langue particulière est toujours la meilleure ; donner un titre comme ça, c’est un niveau de réflexion de collégien...
Je pense que le plus grand atout du C vient du fait qu’il touche directement à l’essence même de l’informatique : « un ordinateur, c’est une suite de bits ». La philosophie simple du C et ses castings
reinterpretassez radicaux ont ce charme qui permet à l’utilisateur de savoir presque toujours en quel code machine cela sera traduit. Ce n’est pas parce que c’est du C que tout langage peut l’appeler, mais parce que l’ABI, elle, est appelable ; en C, c’est simplement que l’on peut prédire — ou que l’on doit prédire — quelle suite de bits correspond à l’entrée et à la sortie. Quand on discute de la faisabilité d’une implémentation, je pense aussi qu’il est important de distinguer ce qui est impossible sur une machine de Turing de ce qui est seulement impossible dans le langage ou le framework qu’on utilise actuellement.Avis de Hacker News
Je ne pense pas qu’il soit nécessaire de justifier pourquoi tous les projets ou tous les programmeurs n’utilisent pas Rust ou Zig
Sur Hacker News et d’autres plateformes, on a tendance à pousser ces langages de manière excessive
Si on obtient déjà de très bons résultats avec C et que les utilisateurs sont satisfaits, il n’y a pas de raison que des gens extérieurs viennent donner des leçons
Il est naturel que les personnes intéressées par l’évolution technologique explorent le potentiel des nouveaux langages
Mais même si chacun est libre de donner son avis de l’extérieur, un projet n’a aucune obligation de l’écouter
Rust réduit l’exposition aux bugs, mais les mêmes catégories de bugs existent toujours
Les développeurs C ont tendance à être plus sensibles aux conditions de concurrence, alors qu’avec Rust il existe un risque de trop faire confiance aux annotations de « sécurité »
En outre, dans Rust, les corrections ne sont pas toujours simples, ce qui peut alourdir la charge de refactoring
Au final, Rust est un langage intéressant, mais ce n’est pas une panacée, et il ne faut pas l’imposer
Des langages comme Rust ou Zig portent l’intention de s’éloigner des schémas traditionnels de la programmation orientée objet
L’OOP a autrefois séduit comme cadre conceptuel apportant une forme d’« illumination », mais en pratique il augmente souvent la complexité et nuit à la modularité
Comme il est naturel d’utiliser une perceuse électrique plutôt qu’un tournevis, quand il existe un meilleur outil, il est normal de s’en servir
Mais les outils et la formation permettant d’écrire du code C sûr doivent eux aussi suffisamment progresser
Je suis un Rustacean assez sérieux, mais je ne pense pas qu’il soit raisonnable de réécrire tous les projets en Rust
Migrer un projet C déjà bien éprouvé vers Rust augmente même probablement le risque d’introduire davantage de bugs à court terme
Cela dit, certains tentent la réécriture en Rust, par exemple Limbo : une réécriture complète de SQLite en Rust
L’un des principaux avantages de SQLite est justement son accessibilité simultanée depuis plusieurs processus ; sans cela, son champ d’usage se réduit
Ils peuvent créer eux-mêmes une nouvelle version et expérimenter pour voir si cela fonctionne
J’ai eu l’expérience de migrer RediSearch vers Rust
C’était lié au grand nombre récent de vulnérabilités CVE
Si SQLite n’a pas ce type de problème, l’intérêt de le migrer vers Rust est limité
Il faudra sans doute des décennies pour bien comprendre les forces et les limites de Rust
En particulier, l’utilité de Rust pour les applications GUI reste encore floue
Pour que Rust atteigne le même niveau de confiance, il faudra peut-être attendre 2040
Comme l’a mentionné Linus, Rust a besoin d’un mécanisme de récupération OOM (Out of Memory)
On peut consulter la discussion associée ici : lien vers la discussion LKML
mallocDans le code embarqué ou noyau, on peut même désactiver complètement les fonctionnalités d’allocation
Autrement dit, Rust fournit déjà un contrôle total sur la mémoire
L’affirmation selon laquelle « il n’existe pas de langage généraliste plus rapide que C » est une comparaison partielle qui ignore le temps des développeurs
Au lieu de passer 5 heures en C à produire un programme qui s’exécute en 4 secondes, il peut être plus réaliste d’en écrire un en 5 minutes dans un autre langage qui s’exécute en 5 secondes
Plus il y a d’utilisateurs, plus même de minuscules écarts de performance ont une valeur cumulée
Rust est encore loin d’être un langage « ennuyeux et stable »
Là où C est géré par un comité conservateur qui protège rigoureusement la compatibilité, Rust privilégie l’innovation plutôt que la compatibilité pour résoudre les problèmes
On peut toujours continuer à compiler du vieux code avec de nouveaux compilateurs
Je pense que c’est préférable à l’approche de C++, qui continue à traîner des fonctionnalités passées
À l’inverse, des langages conçus par comité comme C++ ou Common Lisp ont gagné en complexité
Rust aussi a pris de l’ampleur, donc il faut l’utiliser avec prudence dans l’embarqué ou les systèmes critiques
Je partage l’attitude qui consiste à dire : « ne cassons pas ce qui fonctionne déjà bien »
L’histoire de l’évolution des langages ressemble à une répétition où l’on résout des problèmes pour créer ensuite de nouvelles complexités
C est un exemple emblématique de la philosophie « Worse is Better », et c’est sa simplicité qui a fait son succès pendant des décennies
Rust, à l’inverse, vise le « Right Thing™ »
Aujourd’hui, dans la plupart des environnements, le coût d’implémentation directe a diminué, ce qui peut en faire un meilleur choix
Mais il n’y a pas de raison de migrer de force un projet déjà couronné de succès
Pour un nouveau projet, Rust a de fortes chances d’être un meilleur choix
La simplicité et la stabilité de C sont des avantages sous-estimés
Je pense qu’il vaut mieux affiner la bibliothèque standard ou l’écosystème que continuer à modifier le langage lui-même
Au-delà de la simplicité, la garantie d’un comportement déterministe est aussi importante
J’apprécie par exemple designated initializer, compound literal, alignas, memset_explicit et d’autres fonctionnalités du genre
Personnellement, je pense que C reste le meilleur
Rust a beaucoup de bonnes idées, mais c’est aussi un langage dont les défauts sont bien réels
Pour l’instant, l’ambiance rend encore difficile une discussion lucide sur les problèmes de Rust
On pourrait citer par exemple la courbe d’apprentissage ou la complexité du packaging
L’idée que « tous les systèmes peuvent appeler des bibliothèques C » n’est plus vraie aujourd’hui
Rust et Zig satisfont eux aussi cette exigence
Cela dit, la bibliothèque standard de Rust choisit souvent de paniquer en cas d’OOM plutôt que de récupérer, et la documentation manque sur ce point
extern "C"ouexportpour obtenir la compatibilité ABI CSinon, l’ABI n’est pas définie, ce qui peut être encore plus instable que C++
Ce problème peut devenir particulièrement important dans les distributions Linux qui distribuent des crates Rust