I know this from RFC 246:
- constants declare constant values. These represent a value, not a memory address. This is the most common thing one would reach for and would replace
static
as we know it today in almost all cases.- statics declare global variables. These represent a memory address. They would be rarely used: the primary use cases are global locks, global atomic counters, and interfacing with legacy C libraries.
I don't know what is actually different between the two when I try to maintain a table.
Which one should I choose?
const is a constant value, and cannot be changed. It is compiled into the assembly. static means that it is a value not related to an instance, and it can be changed at run-time (since it isn't readonly ). So if the values are never changed, use consts.
Static variables are generally considered bad because they represent global state and are therefore much more difficult to reason about. In particular, they break the assumptions of object-oriented programming.
Constants are used in programming when a value needs to be available to the program, but it will not change during the execution of the program. What is a variable? A variable is a named container, held by the computer in a memory location.
A const
ant in Rust is immutable. You neither can reassign nor modify it:
struct Foo(u32);
const FOO: Foo = Foo(5);
const mut FOO: Foo = Foo(5); // illegal
fn main() {
FOO = Foo(1); //illegal
FOO.0 = 2; //illegal
}
A static
variable can be mutable and therefore can either be modified or reassigned. Note that writing/modifying a global static
variable is unsafe and therefore needs an unsafe
block:
struct Foo(u32);
static FOO: Foo = Foo(5);
static mut FOO_MUT: Foo = Foo(3);
fn main() {
unsafe {
FOO = Foo(1); //illegal
FOO.0 = 2; //illegal
FOO_MUT = Foo(1);
FOO_MUT.0 = 2;
}
}
When you compile a binary, all const
"occurrences" (where you use that const
in your source code) will be replaced by that value directly.
static
s will have a dedicated section in your binary where they will be placed (the BSS section, see Where are static variables stored in C and C++? for further information).
All in all, stick to a const
whenever possible. When not possible, because you need to initialize a variable later in the program of with non-const
methods, use lazy_static!
.
While both const
and static
can use interior mutability you should never ever do it with a const. Here's an example
use std::sync::atomic::{AtomicU32, Ordering};
static STATIC: AtomicU32 = AtomicU32::new(0);
const CONST: AtomicU32 = AtomicU32::new(0);
fn print() {
println!("static: {}", STATIC.load(Ordering::Relaxed));
println!("const: {}", CONST.load(Ordering::Relaxed));
}
fn main() {
STATIC.store(3, Ordering::Relaxed);
CONST.store(3, Ordering::Relaxed);
print();
}
This compiles fine without any warnings, but leads to unwanted behavoir. Output:
static: 3
const: 0
When using clippy, it will show the two following warnings:
warning: a `const` item should never be interior mutable
--> src/main.rs:4:1
|
4 | const CONST: AtomicU32 = AtomicU32::new(0);
| -----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
| make this a static item (maybe with lazy_static)
|
= note: `#[warn(clippy::declare_interior_mutable_const)]` on by default
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#declare_interior_mutable_const
warning: a `const` item with interior mutability should not be borrowed
--> src/main.rs:8:27
|
8 | println!("const: {}", CONST.load(Ordering::Relaxed));
| ^^^^^
|
= note: `#[warn(clippy::borrow_interior_mutable_const)]` on by default
= help: assign this const to a local or static variable, and use the variable here
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#borrow_interior_mutable_const
warning: a `const` item with interior mutability should not be borrowed
--> src/main.rs:13:5
|
13 | CONST.store(3, Ordering::Relaxed);
| ^^^^^
|
= help: assign this const to a local or static variable, and use the variable here
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#borrow_interior_mutable_const
There's not much practical difference if your variable isn't intended to change.
Constants are inlined at compilation, which means they're copied to every location they're used, and thus are usually more efficient, while statics refer to a unique location in memory and are more like global variables.
Constants are... constant while statics, while still global, can be mutable.
static
vs const
const
:
static
static
:
Example:
static CDF: i32 = 100;
const ABC: i32 = 50;
fn main() {
println!("{}", CDF); // compiler will put in a load instruction here for the static address
println!("{}", ABC); // compiler will put the value 50 here directly
// statics can be mutable
static mut HI: &str = "hi";
// however using mut static is unsafe
unsafe {
HI = "HITHERE";
}
unsafe {
println!("{}", HI);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With