struct A {}
const V: Vec<A> = Vec::<A>::new();
fn push(a: A) {
V.push(a);
}
fn main() {
push(A {});
println!("{}", V.len()); // why 0
}
why the V.len is 0?
struct A {}
const V: Vec<A> = Vec::<A>::new();
fn push(a: A) {
V.push(a);
}
fn main() {
push(A {});
println!("{}", V.len()); // why 0
}
It wouldn't be very constant if you could change it...
Snark aside, the trick to thinking about const
is as if the actual value is substituted directly anywhere the name is mentioned. So V.push(a)
is the same as Vec::<A>::new().push(a)
, creating a temporary and pushing to it, and then it's gone.
A static
would be the way to have something that persists, and you'll need to wrap that in a Mutex
to be able to modify that shared global value.
A Mutex
can't be created at compile time (this is what static
means by constant).
You can use lazy_static!
macro to create it when the program runs.
yeah,it works,thank you
Just curious, any safety concerns behind that (no static mutex)?
I believe the main limitation here is that std
's Mutex
allocates its inner lock in a Box
, and we don't yet have the ability to make allocations in const context.
Everything in a static's initializer runs on "const context", which means that it'll be evaluated at compile time and turned into raw data stuck into the binary. It will eventually be allowed, but there's a lot of logic to figure out surrounding how to make allocations in a const context carry over to static data, and how to get references to those allocations working, etc.
See Heap allocations in constants · Issue #20 · rust-lang/const-eval · GitHub for the current status / working progress of allocations in const context. Once we have that stabilized, we'll likely make all other std functions and constructors which depend on allocation also const
.
The Mutex
from the parking_lot
crate supports const initialization since it doesn't need allocation. There was some efforts to include parking_lot
crate into the stdlib itself, same as we did for hashbrown
crate.
Mutex::new()
(on unix) calls libpthread to create a new runtime mutex object. It doesn't make sense to create a mutex in the compiler's process, embed that mutex's struct in the executable, and then try to use that particular mutex instance in some other process on someone else's machine.
Note that Rust doesn't execute code before main()
, so static
is like loading raw bytes from a file, not like C++'s magical before-main code execution.
This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.