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

  1. Creació de punters crus: let r1 = &num as *const i32; i let r2 = &mut num as *mut i32; converteixen referències segures en punters crus.
  2. Bloc unsafe: El bloc unsafe 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

  1. Definició de funció insegura: unsafe fn dangerous() defineix una funció insegura.
  2. Crida a la funció insegura: La funció dangerous es crida dins d'un bloc unsafe.

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.

© Copyright 2024. Tots els drets reservats