Static items

Syntax
StaticItem :
   static mut? IDENTIFIER : Type = Expression ;

A static item is similar to a constant, except that it represents a precise memory location in the program. A static is never "inlined" at the usage site, and all references to it refer to the same memory location. Static items have the static lifetime, which outlives all other lifetimes in a Rust program. Static items may be placed in read-only memory if the type is not interior mutable. Static items do not call drop at the end of the program.

All access to a static is safe, but there are a number of restrictions on statics:

  • The type must have the Sync trait bound to allow thread-safe access.
  • Statics allow using paths to statics in the constant-expression used to initialize them, but statics may not refer to other statics by value, only through a reference.
  • Constants cannot refer to statics.

Mutable statics

If a static item is declared with the mut keyword, then it is allowed to be modified by the program. One of Rust's goals is to make concurrency bugs hard to run into, and this is obviously a very large source of race conditions or other bugs. For this reason, an unsafe block is required when either reading or writing a mutable static variable. Care should be taken to ensure that modifications to a mutable static are safe with respect to other threads running in the same process.

Mutable statics are still very useful, however. They can be used with C libraries and can also be bound from C libraries (in an extern block).


# #![allow(unused_variables)]
#fn main() {
# fn atomic_add(_: &mut u32, _: u32) -> u32 { 2 }

static mut LEVELS: u32 = 0;

// This violates the idea of no shared state, and this doesn't internally
// protect against races, so this function is `unsafe`
unsafe fn bump_levels_unsafe1() -> u32 {
    let ret = LEVELS;
    LEVELS += 1;
    return ret;
}

// Assuming that we have an atomic_add function which returns the old value,
// this function is "safe" but the meaning of the return value may not be what
// callers expect, so it's still marked as `unsafe`
unsafe fn bump_levels_unsafe2() -> u32 {
    return atomic_add(&mut LEVELS, 1);
}
#}

Mutable statics have the same restrictions as normal statics, except that the type does not have to implement the Sync trait.

Using Statics or Consts

In can be confusing whether or not you should use a constant item or a static item. Constants should, in general, be preferred over statics unless one of the following are true:

  • Large amounts of data are being stored
  • The single-address or non-inlining property of statics is required.
  • Interior mutability is required.