Closed
Description
Recently I've encountered a problem, when I wanted to return a slice of bytes in an integer:
fn to_bytes(num: &u32) -> &[u8] {
&u32::to_le_bytes(*num)
}
(This is an oversimplification of the original code, which is generic over every integer type along with other stuff)
Obviously, since to_le_bytes(*num)
is dropped when the function returns, this piece of code failed the borrow check. Hence my need for as_le_bytes(num)
, as num
is actually alive all this time!
Activity
Mark-Simulacrum commentedon Sep 14, 2019
In this case I believe you can do this via a cast, e.g.
unsafe { slice::from_raw_parts(num as *const u32 as *const u8, 4) }
but I'm not sure if that's entirely well-defined, in particular, the u8 slice would then I believe be over-aligned.It does seem viable that we could provide something like this, though.
ExpHP commentedon Sep 16, 2019
The only method that can possibly be implemented is
as_ne_bytes
. (native endian)as_le_bytes
would be impossible to implement on BE systems, for precisely the same reasons that you cannot write your own function. Sure,num
may be alive, but that would not matter because the memory associated withnum
would not contain those bytes in little-endian order. (and rust slices always have a stride of +1; you can't have a "backwards" slice)I daresay I've never heard anyone mention over-alignment before as a concern to even think about! (except in the context of deallocation, which doesn't matter here)
hch12907 commentedon Sep 22, 2019
It is possible to workaround that by creating a struct, which is a reversed iterator, and return that struct instead for non-ne functions.
That might seem to be too much work for such a simple function though... Or we can just implement
as_ne_bytes
only.ExpHP commentedon Sep 22, 2019
I think the benefits of an iterator over the existing
to_{b,l}e_bytes
methods seem nebulous. That is to say, in whatever use case motivates this feature request (where the author needs a slice instead of an array), I can't imagine how an iterator would help.[-]as_*e_bytes for primitive types[/-][+]as_ne_bytes for primitive types[/+]hch12907 commentedon Sep 11, 2020
Implemented in #76610 for both floats and integers, under the feature gate
int_as_bytes
andfloat_as_bytes
respectively.Auto merge of rust-lang#76610 - hch12907:master, r=LukasKalbertodt
SimonSapin commentedon Oct 8, 2020
Why is a borrow useful? Can’t the calling code assign the result of
to_*e_bytes
to a local variable and borrow that?hch12907 commentedon Oct 11, 2020
It gets problematic when generics are involved:
A
ToBytes
trait is also not doable (at least not in stable AFAIK), since different-sized integers give off a different[u8; N]
.SimonSapin commentedon Oct 11, 2020
If a library wants to be general-purpose enough to expose such a trait, can’t it afford to do the unsafe conversion by itself? Does this really need to be in the standard library?
num_as_ne_bytes
feature #769762 remaining items