Reassignment of static items inside of a function body

Viewed 155

Imagine we have the following code:

fn main() {
    for _ in 0..10 {
        let _ = get_static_ref();
    }
}

struct SomeStruct {
    value: usize
}

fn get_static_ref() -> &'static SomeStruct {
    static MY_STRUCT: SomeStruct = SomeStruct { value: 1 };
    &MY_STRUCT
}

Does the MY_STRUCT gets reassigned on every get_static_ref call, or does the compiler just remove this assignment from function body? Because if it gets reassigned, then it kind of breaks the rule, that non-mut static items are immutable, so it follows that those reassignments shouldn't happen, but that's just my guess.

I was unable to find an explicit explanation for this situation in Rust docs.

3 Answers

If you look at the generated code, you will see that MyStruct is only created once (at compile time) and that the function simply returns the existing instance:

example::get_static_ref:
        lea     rax, [rip + example::get_static_ref::MY_STRUCT]
        ret

example::get_static_ref::MY_STRUCT:
        .asciz  "\001\000\000\000\000\000\000"

The following excerpts from the Rust reference may explain the static MY_STRUCT will be evaluated once at compile time.

  • The static initializer is a constant expression evaluated at compile time.
  • A static item is similar to a constant, except that it represents a precise memory location in the program. All references to the static refer to the same memory location.

No. As for machine code, there is no difference between:

static MY_STRUCT: SomeStruct = SomeStruct { value: 1 };
fn get_static_ref() -> &'static SomeStruct {
    &MY_STRUCT
}

And

fn get_static_ref() -> &'static SomeStruct {
    static MY_STRUCT: SomeStruct = SomeStruct { value: 1 };
    &MY_STRUCT
}

Declaration of static inside function body just limits scope of the name.

Related