Skip to content

as_ne_bytes for primitive types #64464

Closed

Description

@hch12907

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

  1. Mark-Simulacrum commented on Sep 14, 2019

    @Mark-Simulacrum
    Member

    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.

  2. ExpHP commented on Sep 16, 2019

    @ExpHP
    Contributor

    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 with num 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)

    but I'm not sure if that's entirely well-defined, in particular, the u8 slice would then I believe be over-aligned.

    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)

  3. hch12907 commented on Sep 22, 2019

    @hch12907
    ContributorAuthor

    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.

  4. ExpHP commented on Sep 22, 2019

    @ExpHP
    Contributor

    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.

  5. changed the title [-]as_*e_bytes for primitive types[/-] [+]as_ne_bytes for primitive types[/+] on Sep 11, 2020
  6. hch12907 commented on Sep 11, 2020

    @hch12907
    ContributorAuthor

    Implemented in #76610 for both floats and integers, under the feature gate int_as_bytes and float_as_bytes respectively.

  7. added a commit that references this issue on Oct 4, 2020
  8. SimonSapin commented on Oct 8, 2020

    @SimonSapin
    Contributor

    Why is a borrow useful? Can’t the calling code assign the result of to_*e_bytes to a local variable and borrow that?

  9. hch12907 commented on Oct 11, 2020

    @hch12907
    ContributorAuthor

    It gets problematic when generics are involved:

    trait NumberAsBytes {
        fn as_bytes(&self) -> &[u8];
    }
    
    // fn as_bytes(&self) -> &[u8] { self.as_ne_bytes() }
    impl_num_as_bytes!(i8, u8, /* ... */, i64, u64);

    A ToBytes trait is also not doable (at least not in stable AFAIK), since different-sized integers give off a different [u8; N].

  10. SimonSapin commented on Oct 11, 2020

    @SimonSapin
    Contributor

    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?

  11. added a commit that references this issue on May 26, 2021
    f3b10dd
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-feature-requestCategory: A feature request, i.e: not implemented / a PR.T-libs-api[DEPRECATED; DO NOT USE]

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions