Rust est souvent présenté comme « aussi rapide que le C, mais plus sûr ». Cette affirmation est exacte, mais elle passe sous silence l'aspect le plus intéressant : le mécanisme qui garantit sa sécurité est précisément celui qui empêche la plupart des erreurs de programmation.
Les trois règles fondamentales
- Chaque valeur possède exactement un propriétaire
- Lorsque le propriétaire sort de la portée, la valeur est libérée — le compilateur insère automatiquement cette instruction
- À un moment donné, soit il y a plusieurs références en lecture seule, soit il n’y a qu’une seule référence en écriture, jamais les deux à la fois
La troisième règle est la plus importante
Un conflit de données survient lorsque deux flux accèdent simultanément à une même zone de mémoire et qu'au moins l'un d'entre eux effectue une écriture. La règle « plusieurs lectures ou une écriture » correspond précisément à la définition négative de cette situation.
C'est pourquoi le compilateur Rust rejette les programmes présentant des conflits d'accès aux données, même si vous n'avez pas du tout pensé au multithreading lors de l'écriture. C'est là que le ramasse-miettes échoue : il gère le moment où la mémoire est libérée, mais ne contrôle pas qui peut y accéder à quel moment.
Le prix à payer
Les structures de données comportant de nombreux pointeurs réciproques — listes bidimensionnelles, graphes, arbres à pointeurs inversés — deviennent difficiles à représenter. Il faut alors recourir au comptage des références, utiliser des indices à la place des pointeurs, ou accepter un bloc de code non sécurisé mais contrôlé.
La phase d'apprentissage est vraiment intense. Mais la plupart du temps, cette impression que « le compilateur nous complique la vie » s'explique par le fait qu'il signale simplement une erreur qui, dans un autre langage, ne se manifesterait qu'au moment de l'exécution, au moment le plus inopportun.
Thảo luận