Rust és conegut per la seva seguretat de memòria i la seva capacitat per evitar errors comuns com els desbordaments de memòria i les referències nul·les. No obstant això, hi ha situacions en què necessitem més control directe sobre la memòria o volem interactuar amb codi de baix nivell. Per a aquests casos, Rust proporciona una funcionalitat anomenada "Rust insegur" (unsafe
).
Què és Rust Insegur?
El codi insegur en Rust permet:
- Accedir a operacions de baix nivell que no estan garantides per ser segures.
- Interactuar amb codi escrit en altres llenguatges de programació.
- Manipular directament la memòria.
Quan utilitzar Rust Insegur?
- Quan necessites optimitzacions de rendiment que no es poden aconseguir amb el codi segur.
- Quan interactues amb biblioteques de C o altres llenguatges.
- Quan treballes amb operacions de memòria de baix nivell.
Blocs unsafe
Per utilitzar codi insegur, cal encapsular-lo dins d'un bloc unsafe
. Això indica al compilador que el codi dins d'aquest bloc no està subjecte a les garanties de seguretat de Rust.
fn main() { let mut num = 5; // Bloc unsafe let r1 = &num as *const i32; let r2 = &mut num as *mut i32; unsafe { println!("r1: {}", *r1); println!("r2: {}", *r2); } }
Explicació del codi
- Creació de punters crus:
let r1 = &num as *const i32;
ilet r2 = &mut num as *mut i32;
converteixen referències segures en punters crus. - Bloc
unsafe
: El blocunsafe
permet desreferenciar aquests punters crus.
Funcions unsafe
Les funcions també poden ser marcades com a insegures. Això permet que la funció contingui operacions insegures i requereix que qualsevol codi que cridi aquesta funció també estigui dins d'un bloc unsafe
.
unsafe fn dangerous() { println!("Aquesta és una funció insegura!"); } fn main() { unsafe { dangerous(); } }
Explicació del codi
- Definició de funció insegura:
unsafe fn dangerous()
defineix una funció insegura. - Crida a la funció insegura: La funció
dangerous
es crida dins d'un blocunsafe
.
Operacions Insegures
Accés a Memòria
Rust permet l'accés directe a la memòria mitjançant punters crus (*const T
i *mut T
).
let mut num = 5; let r1 = &num as *const i32; let r2 = &mut num as *mut i32; unsafe { println!("r1: {}", *r1); println!("r2: {}", *r2); }
Funcions Externes
Rust permet cridar funcions externes definides en altres llenguatges com C.
extern "C" { fn abs(input: i32) -> i32; } fn main() { unsafe { println!("Abs de -3: {}", abs(-3)); } }
Accés a Mòduls Insegurs
Alguns mòduls de Rust, com std::ptr
, contenen funcions insegures.
use std::ptr; fn main() { let mut num = 5; let r = &mut num as *mut i32; unsafe { ptr::write(r, 10); } println!("num: {}", num); }
Exercicis Pràctics
Exercici 1: Creació de Punter Cru
Objectiu: Crear un punter cru i desreferenciar-lo dins d'un bloc unsafe
.
fn main() { let x = 42; let r = &x as *const i32; unsafe { println!("El valor de r és: {}", *r); } }
Exercici 2: Funció Insegura
Objectiu: Definir i cridar una funció insegura.
unsafe fn increment(x: *mut i32) { *x += 1; } fn main() { let mut num = 5; let r = &mut num as *mut i32; unsafe { increment(r); } println!("El valor de num és: {}", num); }
Resum
- Rust Insegur: Permet operacions de baix nivell que no estan garantides per ser segures.
- Blocs
unsafe
: Necessaris per encapsular codi insegur. - Funcions
unsafe
: Permeten definir funcions que contenen operacions insegures. - Operacions Insegures: Inclouen l'accés directe a la memòria i la crida a funcions externes.
Rust insegur és una eina poderosa que ha de ser utilitzada amb precaució. Assegura't de comprendre completament les implicacions de seguretat abans d'utilitzar codi insegur en els teus projectes.