static mut
- Rust course
- Advanced
- Lesson 33/81
- 4 min
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
use std::sync::atomic::{AtomicUsize, Ordering};
fn main() {
// buraya yaz
}Sample 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));
}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
static SAYAC: AtomicUsize = AtomicUsize::new(0);
SAYAC.____(1, Ordering::SeqCst);
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 |