-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Unsafe Pointer Methods #1966
Unsafe Pointer Methods #1966
Conversation
There's one issue this rfc doesn't quite address. We are wary of methods on box/&/Rc/Arc because they interfere with deref. This isn't directly an issue here, because raw pointers aren't Probably is a straightforward way of speccing this out, but I think it should be explicitly mentioned. |
@Manishearth iirc only deref coercion triggers on |
That's autoderef, deref coercions apply to |
Seems like it wouldn't be too hard to have some compile-fail tests to ensure that coercion is never accidentally introduced slash happens already. |
@Manishearth I don't know what specific code you're possibly imagining as ambiguous? |
Now, I tried this with traits, and it seems like we currently do not coerce |
Yes, that's what I said. Only deref is done with |
👍 for the introduction of On my wishlist I have far more opinionated methods for raw pointers in the PointerExt trait; these have been useful in implementing matrixmultiply, ndarray, low level iterators: raw pointer funhouses. |
|
@gankro Thanks! I have personally experienced this pain a lot, since I write a lot of low-level code... I feel like the names of
I get your points, but I still think I would rather introduce |
What's the use case for pointer arithmetic that can't be solved by taking the address of an index operation? |
@pcwalton Do you mean that we should |
Yeah I briefly considered proposing |
Function argument labels haven't really been brought up in like forever.
…-Manish Goregaokar
On Tue, Apr 4, 2017 at 3:25 PM, Alexis Beingessner ***@***.*** > wrote:
I feel like the names of copy and copy_nonoverlapping should be changed to
indicate the direction of the copy
Yeah I briefly considered proposing copy_to, but I kinda want to hold out
for Rust ever getting function argument labels, so it can be copy(to: x).
I've completely lost track of if that was ever a real proposal or not
though, so copy_to is probably just the right call.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#1966 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/ABivSB1k6HX4yKc6R7P-ABGbvHAcF8Y0ks5rssNOgaJpZM4MyUCF>
.
|
We could finally fix the Edit: for those not in the know:
|
Yes, |
copy_from is a bad idea, because it will just make people get confused about ptr::copy and mess things up. copy_to, on the other hand, does the opposite. |
Perhaps deprecate the ptr:: funcs so that it doesn't look like they provide something different from the new methods? |
The RFC already explains why we shouldn't deprecate them. |
Oh, right. We could still deprecate the copy function though. Idk. |
You can still recover coercion for references by using the explicit method call syntax: Personally I don't like the casual style of the RFC, for example that static functions would stink but still the author wants to keep them. In that sense the style just makes it harder for the RFC to convey its meaning. |
@gankro May be we can silently change the order of parameters for Seriously, though, speaking for myself, knowing the order of parameters for Also, after thinking some more, I agree with others that have said the static functions should be deprecated. The methods seem more elegant and "rustic" than the functions. I think that having duplicate functionality sets a bad precedent which might lead to bloat (unless you can point to other places where this is already standard practice). |
Also, methods can be called with function syntax, though I must confess I don't know exactly what it would look like... maybe something like <*const T>::copy_from(x, y, 23); |
@mark-i-m Yes. I’ve just checked that this compiles: fn main() {
<*const ()>::method(std::ptr::null())
}
trait Trait {
fn method(self);
}
impl<T: ?Sized> Trait for *const T {
fn method(self) {}
} |
@bluss the static functions are bad in most cases, but in rare (IME) cases can be a bit more ergonomic. Since this RFC is targeted at strictly improving ergonomics, it doesn't make sense to regress current ergonomics. @mark-i-m |
I tend to agree with @ubsan, but I would rather this RFC pass than not pass if that's what it comes down to... |
Thanks, @gankro, for taking this on, and apologies for my taking so long to review it! It looks great, and I agree with essentially all of your reasoning. Regarding I think we may want to consider deprecating some of the free functions eventually, but agree that we can treat that as a separate step after we have more experience with the methods. |
🔔 This is now entering its final comment period, as per the review above. 🔔 |
Ok I've come around to adding both, with maybe an intent of strategic deprecation in the longterm. |
I've tried porting pdqsort to use the proposed API and the result can be seen here.
Overall, I'm happy with the API. By the way, a blog post was just published, complaining about unergonomic unchecked arithmetic:
|
@stjepang Would |
@mark-i-m Yes - I like your suggestion! IMO, that negation in nonoverlapping is pretty awkward, and disjoint feels like a more natural synonym. Consider this code: v.add(1).copy_to_nonoverlapping(v, 1);
v.add(1).copy_to_disjoint(v, 1); One more thing: This RFC doesn't mention the |
Heh, I had never heard of offset_to, it was added at the same time as this RFC! I agree nonoverlapping is verbose, but I don't really have any inclination to fix that one. I've personally always had an affinity for its length as a "think twice" thing, since if you're not sure, you should be using plain copy. |
The final comment period is now complete. |
@gankro I am not really sure that's true - especially in Rust, where aliasing is at least rare. |
I have updated the text to add copy_from alongside copy_to. @ubsan it's basically 50/50 in liballoc/collections stuff, because you can't use copy_nonoverlapping for shifting subslices. |
@gankro hmm, it might be different in other codebases. I don't think I've ever personally used memmove, anyways. |
This RFC is still missing a replacement for |
This RFC deprecates nothing. |
Can we merge this RFC? |
Oops apologies! Merged with a tracking issue: rust-lang/rust#43941 |
…bnik Rewrite docs for `std::ptr` This PR attempts to resolve rust-lang#29371. This is a fairly major rewrite of the `std::ptr` docs, and deserves a fair bit of scrutiny. It adds links to the GNU libc docs for various instrinsics, adds internal links to types and functions referenced in the docs, adds new, more complex examples for many functions, and introduces a common template for discussing unsafety of functions in `std::ptr`. All functions in `std::ptr` (with the exception of `ptr::eq`) are unsafe because they either read from or write to a raw pointer. The "Safety" section now informs that the function is unsafe because it dereferences a raw pointer and requires that any pointer to be read by the function points to "a valid vaue of type `T`". Additionally, each function imposes some subset of the following conditions on its arguments. * The pointer points to valid memory. * The pointer points to initialized memory. * The pointer is properly aligned. These requirements are discussed in the "Undefined Behavior" section along with the consequences of using functions that perform bitwise copies without requiring `T: Copy`. I don't love my new descriptions of the consequences of making such copies. Perhaps the old ones were good enough? Some issues which still need to be addressed before this is merged: - [ ] The new docs assert that `drop_in_place` is equivalent to calling `read` and discarding the value. Is this correct? - [ ] Do `write_bytes` and `swap_nonoverlapping` require properly aligned pointers? - [ ] The new example for `drop_in_place` is a lackluster. - [ ] Should these docs rigorously define what `valid` memory is? Or should is that the job of the reference? Should we link to the reference? - [ ] Is it correct to require that pointers that will be read from refer to "valid values of type `T`"? - [x] I can't imagine ever using `{read,write}_volatile` with non-`Copy` types. Should I just link to {read,write} and say that the same issues with non-`Copy` types apply? - [x] `write_volatile` doesn't link back to `read_volatile`. - [ ] Update docs for the unstable [`swap_nonoverlapping`](rust-lang#42818) - [ ] Update docs for the unstable [unsafe pointer methods RFC](rust-lang/rfcs#1966) Looking forward to your feedback. r? @steveklabnik
…bnik Rewrite docs for `std::ptr` This PR attempts to resolve rust-lang#29371. This is a fairly major rewrite of the `std::ptr` docs, and deserves a fair bit of scrutiny. It adds links to the GNU libc docs for various instrinsics, adds internal links to types and functions referenced in the docs, adds new, more complex examples for many functions, and introduces a common template for discussing unsafety of functions in `std::ptr`. All functions in `std::ptr` (with the exception of `ptr::eq`) are unsafe because they either read from or write to a raw pointer. The "Safety" section now informs that the function is unsafe because it dereferences a raw pointer and requires that any pointer to be read by the function points to "a valid vaue of type `T`". Additionally, each function imposes some subset of the following conditions on its arguments. * The pointer points to valid memory. * The pointer points to initialized memory. * The pointer is properly aligned. These requirements are discussed in the "Undefined Behavior" section along with the consequences of using functions that perform bitwise copies without requiring `T: Copy`. I don't love my new descriptions of the consequences of making such copies. Perhaps the old ones were good enough? Some issues which still need to be addressed before this is merged: - [ ] The new docs assert that `drop_in_place` is equivalent to calling `read` and discarding the value. Is this correct? - [ ] Do `write_bytes` and `swap_nonoverlapping` require properly aligned pointers? - [ ] The new example for `drop_in_place` is a lackluster. - [ ] Should these docs rigorously define what `valid` memory is? Or should is that the job of the reference? Should we link to the reference? - [ ] Is it correct to require that pointers that will be read from refer to "valid values of type `T`"? - [x] I can't imagine ever using `{read,write}_volatile` with non-`Copy` types. Should I just link to {read,write} and say that the same issues with non-`Copy` types apply? - [x] `write_volatile` doesn't link back to `read_volatile`. - [ ] Update docs for the unstable [`swap_nonoverlapping`](rust-lang#42818) - [ ] Update docs for the unstable [unsafe pointer methods RFC](rust-lang/rfcs#1966) Looking forward to your feedback. r? @steveklabnik
Copy most of the static
ptr::
functions to methods on unsafe pointers themselves.Also add a few conveniences for
ptr.offset
with unsigned integers.More conveniences should probably be added to unsafe pointers, but this proposal is basically the "minimally controversial" conveniences.
Rendered