rust 2024 will make &mut STATIC_mut a hard error.
When I followed the lint , I got
Now that we have
ptr::addr_of_mut!
, the 2024 edition would be a great time to do @RalfJung's idea from #53639 (comment):Disallow
&MY_STATIC_MUT
and&mut MY_STATIC_MUT
entirely.
ptr::addr_of_mut!(MY_STATIC_MUT)
could even be safe -- unlike taking a reference which isunsafe
and often insta-UB -- and helps encourage avoiding races in the accesses, which is more practical than trying to avoid the UB from concurrent existence of references.(Maybe people will end up just doing
&mut *ptr::addr_of_mut!(MY_STATIC_MUT)
without thinking through all the safety requirements -- in particular, making sure that the reference stops being used before a second reference is created -- but we can't force them to drink.)
Then following the attached link, I got
You must be able to show that every borrow of the
static mut
is not reentrant (as opposed to regular interior mutability, which only requires reentrance-freedom when accessing data), which is almost entirely impossible in real-world scenarios.
Seems the dangerous comes from reentrant, for example, in a signal handler.
But why &mut *ptr::addr_of_mut!(STATIC_MUT)
could be safer?
Indeed, It seems the post was saying &mut *ptr::addr_of_mut!(STATIC_MUT)
is not different with &mut STATIC_MUT:
(Maybe people will end up just doing
&mut *ptr::addr_of_mut!(MY_STATIC_MUT)
without thinking through all the safety requirements -- in particular, making sure that the reference stops being used before a second reference is created -- but we can't force them to drink.)
and the real requirement is stop using the 1st reference before the 2nd was created.
But If &mut STATIC_MUT
is failed to do this, &mut *ptr::addr_of_mut!(MY_STATIC_MUT)
is not better either.
And, if a signal handler needing modify some static variable, seems the only sound method is to make sure the variable re-entrance free, which addr_of_mut is helpless for.
And I can't understand
as opposed to regular interior mutability, which only requires reentrance-freedom when accessing data
even with an interior mutability, for code like this:
// assure interior_modify being called in a thread safe context
// so we don't need a mutex here
fn interior_modify(the_ref: &some_wrapper_of_unsafe_cell)
let mref = unsafe { &mut *the_ref.get() };
// got signal here
// and the signal handler call interior_modify too
mref.modify();
}
is same as &mut STATIC_MUT.
So what is the difference?