Who else has written things like
*raw_ptr = <...> and forgot that this will drop the old content in there and you should really use
ptr.write? I certainly have, and this is also very easy to miss in a review.
So, would it be a good idea to lint against such raw pointer writes unless the type does not need dropping, and suggest using a yet-to-be-introduced
ptr.write_and_drop method instead?
At some point, I stopped dereferencing raw pointers completely, and only use
write methods, manually dropping when needed. The only time I dereference raw pointers is when I need a reference to the object in the memory location (
&*ptr). So yeah, a
ptr.write_and_drop method would make some code clearer. It is also kind of easy to forget that
write doesn't drop.
It is also kind of easy to forget that write doesn't drop.
Having a raw pointer to a type that isn't Copy is already a special kind of crazy.
I agree that
* on raw pointers is nearly always a bad idea, and I've had so many bugs that could be fixed by not allowing it (while I've never actually needed
*, except for turning a raw pointer into a reference)
no reason to disallow it with
Copy types though?
what's the advantage of allowing it ?
ptr.read() works for
Copy too - but now its 2 things you need to learn
&ptr.read() do 2 subtly different things
when working with pointers i wish we had named methods for the basics:
ptr.copy(): copies the memory at pointer - doesn't drop
ptr.write(val): writes val to the memory at pointer - doesn't drop
ptr.write_drop(val): writes val to the memory at pointer, dropping the old value there
ptr.drop(): drops the memory at pointer
ptr.borrow(): borrows the memory at pointer: &T from *const T and &mut T from *mut T
The defaults should be unaligned memory operations, so you need then variants for
You also need variants for
But while verbose, at least the API would be IMO boring and unsurprising.
Why not create the full set of such variants, omitting those combinations (if any) that are intrinsically incompatible? The full set would be 5 * 2^3 = 40 primitives.
It may be infeasible to suggest deprecating the older non-self-documenting forms, but even so the full list would help make Rustaceans aware of the alternative choices they should consider when using raw pointers. In terms of syntax, I suggest appending the suffixes in the order
the advantage of allowing it is that pointers work ergonomically :P
well I think making unaligned the default, that ship has sailed
and in terms of compatibility, there is no reason to cause all the churn involves in people using raw pointers with
I am not talking about "what would we do if this was pre-1.0", that ship has sailed^^
I am trying to see if we can come up with a proposal that has a remote chance of being accepted today
So, I think we should more clearly enumerate the main use cases here, then we'll know more of what the problem might look like.
raw pointers that I use are usually for:
, Copy types, so whatever
, FFI opaque data which must be cleaned up with a foreign call (usually during Drop)
Are there other common use cases for pointers that I'm missing where you'd accidentally forget to Drop a value.
Any type, when you need aliasing
pointers to uninitialized data
I suggested a clippy lint: https://github.com/rust-lang/rust-clippy/issues/4294