A "pure" (read-only) static
(that is, I'm not talking abouth things like thread_local!
or lazy_static!
) is guaranteed to be initialized at compile time (thus requiring a const
expression), and then using it just requires dereferencing a constant address.
Example
#[inline(never)]
fn print_array (at_array: &'_ [i32; 8])
{
println!("array = {:?}", at_array[..]);
}
fn foo ()
{
let array: [i32; 8] = [1, 2, 3, 4, 5, 6, 7, 8];
print_array(&array);
}
In this case, in non optimized code (an optimizer could theoretically const
propagate this, making let
use static
storage too; I can't test this right now), since array
is a local (variable), it lives in the stack and must thus be initialised at runtime, each time the function is called.
That's why, since the values of the array are always the same, it is better to make it live in the static storage (e.g., .rodata
section for an ELF file) where it can be initialised at compile time (it shall live in the executable, and then be loaded into memory by the loader) by declaring the variable static
.
fn foo ()
{
static ARRAY: [i32; 8] = [1, 2, 3, 4, 5, 6, 7, 8];
print_array(&ARRAY);
}
Modulo ARRAY
visibility within the containing mod
ule, above is equivalent to:
static ARRAY: [i32; 8] = [1, 2, 3, 4, 5, 6, 7, 8];
fn foo ()
{
print_array(&ARRAY);
}
To be honest, another option would be to declare the variable const
and let the compiler choose between static
or stack storage; I guess that's what I should have used in the mentioned post.
The equivalent to Rust's static
in C
is either a private global variable (i.e., declared (anywhere) with the static
modifier) or a public global variable (i.e., declared outside any function body, without the static
modifier).
(Note: once I have the setup (on the phone right now) I will edit this post with the different disassemblies of foo()
)