Skip to content
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

Raw pointer cast functions #202

Open
bravely-beep opened this issue Jul 27, 2023 · 4 comments
Open

Raw pointer cast functions #202

bravely-beep opened this issue Jul 27, 2023 · 4 comments

Comments

@bravely-beep
Copy link

Would it make sense to include cast functions that handle raw pointers?

  • fn cast_ptr(a: *const A) -> *const B
  • fn cast_mut_ptr(a: *mut A) -> *mut B
  • fn cast_slice_ptr(a: *const [A]) -> *const [B]
  • fn cast_mut_slice_ptr(a: *mut [A]) -> *mut [B]

This would be useful when working with data that is unsafe to take references to (e.g. volatile IO memory).

@zachs18
Copy link
Contributor

zachs18 commented Jul 28, 2023

I would not necessarily be opposed to these, but a few notes:

  1. (I assume their failure conditions and semantics would be mostly the same as cast_ref/cast_mut/cast_slice/cast_slice_mut? Otherwise I don't really see the point; if they are meant to always succeed you can just as-cast them.)
  2. As has been mentioned in other issues/PRs, bytemuck already has a lot of functions (Add cast_{arc,rc} (and slice and try), and {wrap,peel}_{arc,rc}. #132 (comment))
  3. If these were added, I would expect the corresponding try_ functions to also exist.
  4. I would expect the ordering of the words in the function names to match the existing functions, i.e. either ptr between slice and mut (my preference: cast_ptr_mut/cast_slice_ptr_mut) or ptr after mut (cast_mut_ptr/cast_slice_mut_ptr). For the second case, IMO it would read better if cast_ptr/cast_slice_ptr had const where the *mut versions have mut.
  5. cast_slice_ptr and cast_slice_ptr_mut could not (currently) be (fully) implemented on stable AFAIK, since there is no (fully "blessed") way to get the length of a general slice pointer on stable (<*const [T]>::len is unstable. There are some partial workarounds/polyfills listed on the tracking issue but none are completely general and safe.).
    • Also, making a raw slice pointer with std::ptr::slice_from_raw_parts was only stabilized in Rust 1.42.0 which is above bytemuck's MSRV of 1.34.0, so the slice pointer functions would probably have to be behind a feature flag anyway.
  6. Raw slice pointers are allowed to have element-lengths that would give them a byte-length longer than usize::MAX bytes, which would introduce an additional failure case to cast_slice_ptr(_mut) that doesn't exist for other casts: "Casting this slice pointer from the source to destination type would overflow the element-length of the slice", though this could reasonably be folded into PodCastError::SizeMismatch I suppose (PodCastError is not #[non_exhaustive], so a new variant could not be added semver-compatibly), or a new error type could be added similar to CheckedCastError. Example:
let too_long: *const [u32] = std::ptr::slice_from_raw_parts(std::ptr::null(), usize::MAX);
let what_error_should_this_return: Result<*const [u8], PodCastError> = try_cast_slice_ptr(too_long);

@Lokathor
Copy link
Owner

Yeah, there's a lot more small design work than it might seem at first.

Personally, for volatile access i have the voladdress crate, which has always served my needs well enough to not bother with raw pointers in bytemuck

@simonask
Copy link

If I may, I would suggest to leave slice pointer casts out for now, but add support for NonNull pointers.

I'm doing this in some of my projects, and I'm basically copy-pasting cast_ref and friends. These would be trivial additions.

@zachs18
Copy link
Contributor

zachs18 commented Feb 20, 2024

there is no (fully "blessed") way to get the length of a general slice pointer on stable.

Since Rust 1.75.0, with the stabilization of wrapping_byte_add it is possible to write a correct polyfill of <*mut [T]>::len on stable.

rust-lang/rust#71146 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants