Home
# Unsafe Rust * Compilateur **très pointilleux**: * garanties de sécurité mémoire **très fortes**, * décidées dès **la compilation**. * Des fois le compilateur prend **trop de précautions**: * Peut rejeter un code valide lors d'un doute, * Rust `unsafe` donne des pouvoirs supplémentaires, * Tant pis si l'utilisateur·trice les utilise mal. * Les opérations de bas niveau sont `unsafe` par définition (p.ex. interactions avec l'OS). --- # Nouveaux pouvoirs * Déréférencer un pointeur brut, * Appeler une fonction ou une méthode `unsafe`, * Accéder à une variable statique mutable ou la modifier, * Implémenter trait `unsafe`, * Accéder aux champs des unions. --- # Les blocs `unsafe` ```rust [1-3|4-6] unsafe { // code unsafe }; let bla = unsafe { // le code peut retourner une valeur }; ``` --- # Mais attention * Garanties mémoires sur les références **ne disparaissent pas** en mode `unsafe` ```rust compile_fail let a = 12; unsafe { let b = &a; let c = &mut a; }; ``` --- # Le type pointeur brut ```rust [1-2|3-4] let a = 12; let ptr_a: * const i32 = &a as * const i32; let mut b = 24; let mut_ptr_b: * mut i32 = &mut b as * mut i32; ``` --- # Propriétés des pointeurs bruts * `* const T`/`* mut T`: on ne peut/peut pas modifier la valeur pointée, * Aucune garantie que le mémoire pointée est valide, * Pas de libération automatique de la mémoire pointée lors de la sortie de la portée, * Possibilité d'allouer des données sur le tas: `alloc()` `dealloc()`. --- # Déréférencement d'un pointeur brut ```rust [1-3|4-6] let mut a = 12; let ptr_a = &a as * const i32; let mut mut_ptr_a = &mut a as * mut i32; unsafe { *mut_ptr_a = 20; println!("{}, {}", *ptr_a, *mut_ptr_a); } ``` --- # Fonction `unsafe` ```rust [1|2] unsafe fn attention_not_safe() { // everything in here is implicitly annotated unsafe } unsafe { attention_not_safe(); } ``` --- # Remarques * Garder le code `unsafe` aussi petit que possible, * Aide à trouver où peuvent se trouver les erreurs de mémoire, * Cacher le code `unsafe` dans une API `safe`, * Permet de communiquer avec du code "externe" (des lib C), * Annotation `unsafe` d'un bloc: fait tourner ce code c'est promis il marche, * Annotation `unsafe fn`: attention cette fonction à des contraintes particulières.