Le C++ est un langage de programmation puissant et largement utilisé, réputé pour sa flexibilité et ses performances. Cependant, l'un de ses inconvénients historiques est l'absence de fonctionnalités intégrées de sécurité mémoire, ce qui peut conduire à divers types de bugs liés à la mémoire, comme les dépassements de tampon, les pointeurs pendants et les fuites mémoire.
C'est un problème bien connu qui persiste depuis des décennies, et de nombreuses tentatives ont été menées pour y remédier. Malheureusement, aucune n'a apporté de solution complète.
Qu'a-t-on fait au fil des ans pour améliorer la sécurité mémoire du langage ?
Ramasse-miettes
Un ramasse-miettes (Garbage Collector, GC) est un mécanisme utilisé dans les langages de programmation et les environnements d'exécution pour récupérer automatiquement la mémoire qui n'est plus utilisée par le programme. Son objectif principal est de gérer l'allocation et la libération de la mémoire, soulageant les développeurs du fardeau de la gestion manuelle et aidant à prévenir les erreurs courantes liées à la mémoire, comme les fuites et les pointeurs pendants.
Pour le C++, en 2008, une prise en charge minimale du ramasse-miettes et de la détection des fuites fondée sur l'accessibilité a été ajoutée à C++0x. Depuis, de nombreuses propositions ont été avancées. Malheureusement, aucune d'elles n'a couvert tous les cas, et le ramasse-miettes a été définitivement retiré en C++23.
Vérificateurs d'emprunts
Le vérificateur d'emprunts (borrow checker) est une fonctionnalité clé du langage de programmation Rust qui garantit la sécurité mémoire et prévient les courses de données en analysant statiquement, à la compilation, la possession et l'emprunt des références dans un programme. C'est l'une des innovations centrales de Rust et un aspect fondamental de son modèle de possession.
La question est donc : pourquoi ne pas apporter ce mécanisme au C++ ?
En 2021, une équipe de Google Chromium a tenté de répondre à cette question. Dans leur document de conclusion, ils concluent :
À première vue, il semblerait que nous ayons réussi à écrire un vérificateur d'emprunts pour C++, avec les types définis ci-dessus. Malheureusement, ce n'est pas le cas.
En effet, comme le décrit leur document, de nombreux défis restaient non résolus, et le vérificateur d'emprunts n'a finalement pas pu être ajouté au C++.
Vérificateurs à l'exécution
Les vérifications à l'exécution en C++ englobent divers mécanismes et techniques pour valider le comportement d'un programme et détecter les erreurs pendant son exécution. En C++, on les appelle les sanitizers. Ils font partie des compilateurs Clang et GCC et fournissent une instrumentation à l'exécution pour intercepter les erreurs pendant l'exécution du programme. Ces sanitizers sont généralement utilisés pendant les phases de développement et de test pour identifier et corriger les problèmes. Cependant, ils ne sont généralement pas utilisés en production, et de nombreux problèmes qui surviennent en production peuvent ne pas être rencontrés pendant le développement.
Même pendant le développement, les sanitizers ne sont pas universellement adoptés et ne sont donc pas toujours utilisés.
Et maintenant ?
Actuellement, Stroustrup travaille sur une solution potentielle à ce problème de sûreté : les profils C++ (C++ profiles), c'est-à-dire un ensemble de règles qui, lorsqu'elles sont suivies, offrent des garanties de sûreté spécifiques. Ils seraient définis par la norme ISO C++ et traiteraient les problèmes de sûreté courants comme les pointeurs et les intervalles de tableaux.
Il a créé un dépôt GitHub, où chacun peut soumettre des suggestions et où il peut partager ses brouillons, contribuant ainsi à bâtir une communauté capable de faire avancer ce travail dans un délai raisonnable.
Conclusion
Le C++ a jusqu'ici résisté aux tentatives d'introduire une sécurité mémoire complète dans le langage. Cependant, trouver une solution définitive à ce problème majeur est devenu de plus en plus urgent. Peut-être devrions-nous envisager d'ajouter ce problème aux problèmes du prix du millénaire. :)
