Rust
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.
Exercise 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.
Show example solution
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));
}
Test yourself
-
Which is the best choice for a global counter across threads?
- static SAYAC: AtomicUsize
- static mut SAYAC: usize
- const SAYAC: usize
- let SAYAC
Show answer
static SAYAC: AtomicUsize — Atomics need no unsafe and cause no data races; they can be declared with static because they provide interior mutability.
-
Atomic increment
static SAYAC: AtomicUsize = AtomicUsize::new(0);
SAYAC.____(1, Ordering::SeqCst);
Show answer
static SAYAC: AtomicUsize = AtomicUsize::new(0);
SAYAC.fetch_add(1, Ordering::SeqCst);
-
Global and safety
- static mut X
- Every access unsafe
- static X: AtomicUsize
- Safe
- LazyLock
- Lazy, safe initialization
- const X
- Immutable, inlined
Next lesson: FFI call