External Publication
Visit Post

Impact of Static Variables on API Soundness

Rust Internals [Unofficial] February 26, 2026
Source

I have a question regarding the policy for declaring API safety when it depends on the value of static variables. In the example below, the module FooSys contains a static variable PTR with internal mutability and two public APIs. Can the API do_critical_task be declared safe?

The function do_critical_task requires that PTR is either null or points to CONFIG. In the current module, this is guaranteed because PTR can only have these two states. However, future modifications to the module could introduce additional states or allow PTR to be changed, which could break this guarantee.

My specific questions are as follows:

  1. In the current implementation, I believe do_critical_task can be declared safe. Is this correct?
  2. If PTR remains private, but additional invalid states become possible, then do_critical_task cannot be declared safe, correct?
  3. If PTR is made public (but not to other crates), meaning that additional invalid states could be introduced from outside the module, can do_critical_task still be declared safe?
mod FooSys {
    use std::{ptr, sync::atomic::{AtomicPtr, Ordering}};

    /// Static atomic pointer pointing to system configuration
    static PTR: AtomicPtr<u32> = AtomicPtr::new(ptr::null_mut());

    /// Initialize the system and set PTR to point to a valid static resource
    pub fn initialize_system() {
        // Static configuration/resource
        static CONFIG: u32 = 42;

        // Store the pointer into the atomic variable
        PTR.store(&CONFIG as *const u32 as *mut u32, Ordering::SeqCst);
    }

    pub fn do_critical_task() {
        // Load the raw pointer from the atomic variable
        let ptr = PTR.load(Ordering::SeqCst);

        // Check if pointer is null (not initialized)
        if !ptr.is_null() {
            unsafe { read_config(ptr); }
        }
    }

    // Safety: `ptr` must point to a valid configuration.
    unsafe fn read_config(ptr: *mut u32) {
       ...
    }
}

Discussion in the ATmosphere

Loading comments...