Search code examples
rustendiannessbytebuffer

Why does to_be_bytes() and to_le_bytes() do the opposite of what I expect here?


Maybe the question should be "Why do I expect to_be_bytes() and to_le_bytes() to do the opposite here?", but anyways, here is the situation:

fn main() {
    let buf: [u8; 2048] // Buffer I use to receive UDP messages

    let (_, entry, _) = unsafe { buf[14..].align_to::<u16>() };
    // In memory entry looks like: 00 44 16 15   21 04 03 5a   03 67 03 6a   03 64 88 91

    let [first, second] = entry[0].to_be_bytes();
    
    assert_eq!(first, 0x44);
    assert_eq!(second, 0x00);
}

Shouldn't it be the opposite? Isn't big endianness like preserving the order in memory?


Solution

  • Big endian means the high byte is stored (or transmitted) first, meaning at the lowest address. Intel processors are little endian, meaning the low byte is stored in the low address.

    There are some advantages to each, but generally big endian is preferred, which is why network protocols and portable data formats are usually big endian. Intel remains little endian for compatibility with older versions. Some CPUs have modes that can switch between the two, but Intel never did that.