CodeBlanks Logo Icon CodeBlanks

static mut

Manage global variables with static mut.

static mut

static variables live at a single address for the whole program's lifetime. static mut gives a mutable global, but every access is unsafe, because if two threads change it at once there's a data race. Since Rust 2024, taking a reference to a static mut is an error by default:

static mut ESKI_SAYAC: u32 = 0;

unsafe {
    ESKI_SAYAC += 1;   // open to data races
}

In modern Rust there's almost always a better option: atomic types, Mutex, OnceLock or LazyLock.

Safe globals

Atomic types and lazy initialization provide global state without unsafe:

use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::LazyLock;

static SAYAC: AtomicUsize = AtomicUsize::new(0);
static AYARLAR: LazyLock<Vec<String>> = LazyLock::new(|| {
    vec![String::from("varsayılan")]   // runs once, on first access
});

SAYAC.fetch_add(1, Ordering::SeqCst);

Ordering decides in what order other threads see the change; if unsure, SeqCst is the strongest and safest option.

Practice Atomic global counter

Declare static SAYAC: AtomicUsize and write fn artir() that increments it with fetch_add. Call artir three times and print the value with load.

Starter code

main.rs
use std::sync::atomic::{AtomicUsize, Ordering};

fn main() {
    // buraya yaz
}

Sample solution

main.rs
use std::sync::atomic::{AtomicUsize, Ordering};

static SAYAC: AtomicUsize = AtomicUsize::new(0);

fn artir() {
    SAYAC.fetch_add(1, Ordering::SeqCst);
}

fn main() {
    for _ in 0..3 {
        artir();
    }
    println!("{}", SAYAC.load(Ordering::SeqCst));
}

Expected output

3

Questions and answers

Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.

1 Which is the best choice for a global counter across threads?

  • static SAYAC: AtomicUsize Correct answer
  • static mut SAYAC: usize
  • const SAYAC: usize
  • let SAYAC

Explanation: Atomics need no unsafe and cause no data races; they can be declared with static because they provide interior mutability.

2 Atomic increment

Question
static SAYAC: AtomicUsize = AtomicUsize::new(0);
SAYAC.____(1, Ordering::SeqCst);
Answer
static SAYAC: AtomicUsize = AtomicUsize::new(0);
SAYAC.fetch_add(1, Ordering::SeqCst);

Explanation: fetch_add increments the value atomically and returns the old value.

3 Global and safety

Term Meaning
static mut X Every access unsafe
static X: AtomicUsize Safe
LazyLock Lazy, safe initialization
const X Immutable, inlined

All lessons in Advanced