Hacker News new | past | comments | ask | show | jobs | submit login

Neither of those are best practice; you should use some kind of uint16_from_le() macro.



Yep. Rust's APIs do this right. Eg u32::to_be_bytes() / u32::to_le_bytes() and u32::from_be_bytes() / u32::from_le_bytes().

There's also methods for native byte order, but thats almost never the right thing to use.

I think Go does the same thing. I heard about this approach first from Rob Pike, who would rant about this to anyone who would listen. He said to think of "bytes on disk/network" and "an integer in RAM" as different types that you need to convert between. When you do, the API should specify the endian-ness of the bytes on disk / in the network. He argued you shouldn't do "byte swapping" at all based on endianness. Just parse the int, byte at a time and use the same code on every computer.

The real problem is that C makes it easy to convert between a pointer to an integer and a pointer to some bytes in RAM. Just never do that using pointer casting, and everything works out great.

https://doc.rust-lang.org/std/primitive.u32.html#method.to_b...


We agree. I'm writing it out as an example. In real life you would put it in some kind of helper function. (Or macro.) I'm not suggesting writing it out inline on every access.


In that case I disagree. You can't guarantee that the shift-and-or will be optimized out by the compiler in cases where no swapping is needed so you're making the code potentially slower.




Join us for AI Startup School this June 16-17 in San Francisco!

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: