Rust Static Variables
A static variable is a value that lives outside every function, for the whole run of the program. Every part of the program can reach the same one value.
Declare a static
Names use SCREAMING_SNAKE_CASE, like constants. Reading an immutable static is safe, just like reading a let value โ no block needed:
static MAX_LIVES: u32 = 3;
println!("lives = {MAX_LIVES}");One fixed address
A static has one fixed address in memory: every use reads the same single value:
let a = &MAX_LIVES;
let b = &MAX_LIVES;
println!("same = {}", std::ptr::eq(a, b));Change a static mut (unsafe)
Write static mut for a changeable global. Reading or writing it is unsafe. Two threads could clash on it. So it is read back here through a raw pointer:
static mut COUNTER: u32 = 0;
unsafe {
COUNTER += 3;
println!("counter = {}", *(&raw const COUNTER));
}Wrap it in an unsafe helper
Mark a helper unsafe fn. Write a // SAFETY: note when it touches a static mut. Then callers know the rule:
// SAFETY: bump is only ever called from the main thread.
unsafe fn bump() {
unsafe { COUNTER += 1; }
}Example
static HELLO_WORLD: &str = "Hello, world!";
static mut COUNTER: u32 = 0;
unsafe fn add_to_count(inc: u32) {
unsafe {
COUNTER += inc;
}
}
fn main() {
println!("value is: {HELLO_WORLD}");
unsafe {
add_to_count(3);
println!("COUNTER: {}", *(&raw const COUNTER));
}
}Key points
- A const is different: the compiler may copy its value into each place that uses it
- Prefer a Mutex or an atomic when several threads need one shared changing value.
- A static never gets taken down when a function returns.
- A static variable is one shared value that lives for the whole program outside every function.
In this example, HELLO_WORLD is an immutable static, so main reads it safely and prints value is: Hello, world!. COUNTER is a static mut. The helper add_to_count is an unsafe fn: inside its own unsafe block it adds 3. main calls it inside unsafe. Then it reads COUNTER through a raw pointer. That is the safe way to look at a static mut. And it prints COUNTER: 3.
Note
The compiler then checks the sharing for you.
Try it Yourself
Edit the code, then press Run.
Running is simulated ยท Rust Playground
Exercise
Why is changing a static mut unsafe?