Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.
Sign upAdd ptr::{read,write}_unaligned #1725
Conversation
eddyb
reviewed
Aug 22, 2016
| # Alternatives | ||
| [alternatives]: #alternatives | ||
|
|
||
| We could simply not add these, however figuring out how to do unaligned access properly is extremely unintuitive: you need to cast the pointer to `*mut u8` and then call `ptr::copy_nonoverlapping`. |
This comment has been minimized.
This comment has been minimized.
eddyb
Aug 22, 2016
Member
What about passing the alignment explicitly, with the functions proposed here being only for an alignment of 1?
That way, instead of always doing stack copies, they can generate optimal LLVM IR for that given alignment.
They could also be used with larger alignments to potentially hint that, e.g. SIMD can be used, although that works better for variants of the ptr::copy{,_nonoverlapping} functions.
Now is that better than having the alignment as part of the pointer?
I don't know, #[align(1) *mut u32 crossed my mind and it's good enough for some cases, but doesn't work with generics (would have to be something that works with polymorphic constants, i.e. part of the typesystem).
This comment has been minimized.
This comment has been minimized.
Amanieu
Aug 22, 2016
Author
Contributor
I think these use cases can be covered by using a newtype with an explicit alignment attribute:
#[align(1)]
struct UnalignedU32(u32);This makes more sense since the alignment is attached to the type that is pointed to rather than the pointer itself.
This comment has been minimized.
This comment has been minimized.
eddyb
Aug 22, 2016
•
Member
I was thinking about taking a reference to a packed field, to be clear. Otherwise we could do:
#[align(1)]
struct Unaligned<T>(T);
struct AlignAs<T, U>([U; 0], Unaligned<T>);
BurntSushi
added
the
T-libs
label
Aug 22, 2016
This comment has been minimized.
This comment has been minimized.
|
On architectures that allow unaligned accesses without faulting, these should become aliases for direct pointer reads and writes. These should only become a full call to |
Amanieu
referenced this pull request
Sep 13, 2016
Closed
ptr::read and ptr::write (and others?) should specify alignment requirements in their contract #36450
This comment has been minimized.
This comment has been minimized.
bluss
commented
Sep 26, 2016
|
@joshtriplett llvm already compiles copy_nonoverlapping that way, what I've seen. |
This comment has been minimized.
This comment has been minimized.
|
It looks like the only concern here is the ability to tell Rust how to optimize for alignments other than 1, and there's no way to do it for references to pre-existing packed struct fields. @eddyb Do you feel strongly about the importance of specifying alignment to these functions? This otherwise looks like a simple RFC to push through. |
brson
self-assigned this
Oct 10, 2016
This comment has been minimized.
This comment has been minimized.
comex
commented
Oct 10, 2016
|
Might it be better to explicitly specify an Putting unaligned addresses in a |
This comment has been minimized.
This comment has been minimized.
parched
commented
Oct 10, 2016
|
I think I agree with @comex here, alignment should be handled by the type system, not manually by users. Although, I don't think unaligned types like |
This comment has been minimized.
This comment has been minimized.
|
@comex You can't run a destructor on an unaligned object because that would create a misaligned These function are merely convenience wrappers around |
This comment has been minimized.
This comment has been minimized.
comex
commented
Oct 11, 2016
•
|
Oh, good point. And in fact, after some searching, this RFC purports to ban generic packed structs altogether due to the issue with Drop on their contents, though that rule doesn't seem to be implemented... |
This comment has been minimized.
This comment has been minimized.
|
Based on @Amanieu's statement that "these function are merely convenience wrappers around memcpy and are only useful in unsafe code", I tend to think we don't need a lot of ceremony here to protect users from themselves. This is surfacing an unsafe feature for a specialized purpose. Those that need to do a lot of unaligned work with some guarantees can develop those abstractions and test them in practice, rather than us speculate about what would be useful. Still hoping to hear from @eddyb about the alignment. |
This comment has been minimized.
This comment has been minimized.
|
Sorry, that ping got lost among the other messages. If the type-based approach can be used with the existing functions with some pointer casting, then we don't even need these new functions AFAICT, and if they can't be used, they're a bit limited. The problem with non-orthogonal functions is that you might also want unaligned (or differently aligned?) volatile variants of this, for example. There's potential candidates you'd keep adding. If none of those concerns actually apply, then I have nothing against this RFC in its current form. |
This comment has been minimized.
This comment has been minimized.
|
I don't think there is much of a use case for unaligned volatile accesses. These will likely be broken up into multiple memory accesses by the hardware, which somewhat defeats the point of volatile. |
This comment has been minimized.
This comment has been minimized.
|
I'm inclined to move this to FCP to see if we can stir up more opinions. It looks to me like these are the major points:
My inclination is that this is useful as-is for a pretty common case, and low risk. But I also think the case both for and against are not that strong. We don't need this in tree but it would be good to have some signaling that one can do unaligned load and store, and this is how. @rfcbot fcp merge |
This comment has been minimized.
This comment has been minimized.
rfcbot
commented
Nov 4, 2016
•
|
Team member @brson has proposed to merge this. The next step is review by the rest of the tagged teams: No concerns currently listed. Once these reviewers reach consensus, this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up! See this document for info about what commands tagged team members can give me. |
This comment has been minimized.
This comment has been minimized.
hsivonen
commented
Nov 8, 2016
|
Having this would have saved me time, so +1 for having obvious ways to dereference unaligned pointers to SIMD types in particular. One bikeshed question though: Is there a good reason for these being functions as opposed to methods on pointer types like the |
This comment has been minimized.
This comment has been minimized.
read_volatile() and write_volatile() are free functions in core::ptr, not methods. |
This comment has been minimized.
This comment has been minimized.
rfcbot
commented
Nov 12, 2016
|
|
rfcbot
added
the
final-comment-period
label
Nov 12, 2016
This comment has been minimized.
This comment has been minimized.
rfcbot
commented
Nov 22, 2016
|
The final comment period is now complete. |
alexcrichton
referenced this pull request
Nov 23, 2016
Closed
Tracking issue for ptr::{read,write}_unaligned #37955
alexcrichton
merged commit 35ad6c5
into
rust-lang:master
Nov 23, 2016
This comment has been minimized.
This comment has been minimized.
|
Looks like no new issues came up, so merging! Thanks again for the RFC @Amanieu! Tracking issue: rust-lang/rust#37955 |
This comment has been minimized.
This comment has been minimized.
bluss
commented
Dec 12, 2016
|
I realize Rust is not C, but I'll just remind us of the difference here. I'm late now, but something like this could have been part of the RFC. With a background in C, it's strange to even pass around raw pointers that are not well aligned for their pointee type. (Casting to create such a pointer is UB in C!). In Rust it's a useful feeling anyway, because almost all consumers of raw pointers have the same requirement (well aligned for pointee type). But we make note that this is not an invariant of the raw pointer type itself in Rust. Yet, many implementations may feel it's more precise to store unaligned pointers as |
bluss
reviewed
Dec 12, 2016
| ptr::copy_nonoverlapping(&v as *const _ as *const u8, | ||
| p as *mut u8, | ||
| mem::size_of::<T>()); | ||
| } |
This comment has been minimized.
This comment has been minimized.
bluss
Dec 12, 2016
forget(v) is missing in the reference implementation here; this should move v into the new location, just like write does.
This comment has been minimized.
This comment has been minimized.
|
cc @rust-lang/lang re: @bluss's comment, which has some overlap with the unsafe guidelines work. Just want to make sure everyone is aware/on board. |
This comment has been minimized.
This comment has been minimized.
|
Please update the Rendered link to point to the final text if you get a chance. Thanks! |
This comment has been minimized.
This comment has been minimized.
|
Updated |
Amanieu commentedAug 22, 2016
•
edited by sfackler
Rendered