3

My best current effort is

// `value` is a `&[u8]`
let v = unsafe { slice::from_raw_parts(value.as_ptr() as *const i8, value.len()) };

It seems overkill to need unsafe for this. I'd like this to be zero cost.

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
benjumanji
  • 1,395
  • 7
  • 15
  • > Casting between two integers of the same size (e.g. i32 -> u32) is a no-op https://doc.rust-lang.org/reference/expressions/operator-expr.html#semantics – Mihail Malostanidis Nov 18 '20 at 00:03

1 Answers1

5

Your code is as zero cost as it can be already. But it has to use unsafe code underneath because not all kinds of slice conversions are guaranteed to be safe by the compiler when done through slice::from_parts or mem::transmute. Whichever "safe" function is suitable here would likely enclose that while ensuring that the item types are compatible with this conversion (i.e. same size and memory alignment).

You may be able to find multiple crates which proper testing and maintenance for this conversion. The crate safe-transmute implements this conversion, while supporting more bound guards and alignment checks (disclaimer: I'm one of the collaborators).

use safe_transmute::transmute_many_pedantic;

let value: &[u8] = &[0x00, 0x01, 0x12, 0x24, 0x00];
let words: &[i8] = transmute_many_pedantic(values)?;
E_net4
  • 27,810
  • 13
  • 101
  • 139