I have a static variable of type Option, I want to initialize it once, but I don't want to make it mutable otherwise I will need to synchronize access to it, which is unnecessary because it will not be changed afterwards.
For this purpose I initialize it once using a pointer. Is this a UB?
And what about non-static variables, too?
Mutating memory through a pointer that does not have write access is always UB, doesn't matter if it points to a static or non-static memory. What you want can be done using just safe code with std::sync::OnceLock
/std::sync::LazyLock
Unfortunately, I am in a no_std environment and cannot use it.
Pointer itself has write access, I didn't quite understand you.
If you have a non-mut X and a pointer to X, the pointer never can have write permission.
Using such a pointer to write to X is always UB.
So, you should change your code.
Initializing statics once and then just reading them is the primary use case of std::sync::LazyLock.
In that's not the right typecore
there's LazyCell
which you can use instead of LazyLock
. You just have to access it via a function call.
lazy_static is no_std
and does not depend on alloc
as far as I can tell.
Would static_cell crate suit your needs? We use it in our embedded code and it's great
Here's a no_std Lazy implementation Lazy in spin::lazy - Rust
you can use once_cell::sync::OnceCell
or once_cell::sync::Lazy
on #![no_std]
with the critical_section
feature enabled, which should work on many embedded platforms. If you can use alloc
, you can also use once_cell::race::OnceBox
which doesn't need critical_section
assuming you have atomics.