Transmute &[u32] to &[u8]?

I think there is a 1-3 line solution to this involving std::mem::transmute , but I am not confident in my knowledge.

  1. why do you need this? I built a [u32], uploading a texture to OpenGL/WebGL expects a &[u8]

  2. alignment issues? we are going u32 -> u8, so I think it should be fine

  3. I want this to be O(1), i.e. don't build Vec, data is on the order of 4MB, and called frequently

Is there some way to safely transmute this ? We only have a &[u32]; we can NOT consume the original [u32].

This method is sound:

fn u32_to_u8(arr: &[u32]) -> &[u8] {
    let len = 4 * arr.len();
    let ptr = arr.as_ptr() as *const u8;
    unsafe {
        std::slice::from_raw_parts(ptr, len)
    }
}
3 Likes

In this thread, you can find suggestions of crates that encapsulate this kind of trivial transmutation.

I am not sure if it is relevant in this case, but these days, due to compile time, I am pedantic about using as few crates as possible

It's never transmute when it comes to indirection. You can transmute values, but transmuting is not transitive via references or pointers. If you have T and U such that transmuting from T to U is sound, then that does not imply that transmuting &T to &U or *const T to *const U or Rc<T> to Rc<U> would also be sound. And even if it were sound, it might not do what you think it should.

Casting between pointers and then dereferencing them leads to the transmuting of the pointed value, not that of the pointer, and vice versa. Please, do not use transmute() for converting between pointer or reference types.

1 Like

Would it be possible to provide a concrete example of how things would break? (Intuitively, what you say sounds reasonable, but having a concrete example to anchor all this would be helpful in understanding how things go bad.)

Well, transmuting &[u32] to &[u8] would lead to the wrong length.

5 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.