How to push A to const Vec

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?

1 Like

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.

3 Likes


i modified const to static, but got this error

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.

1 Like

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.

2 Likes

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.

2 Likes

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.

1 Like

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.