C · 5 · Systems C25 / 35 · 71%
Endianness & Byte Order
The same 4 bytes mean different numbers on different machines.
Examples: htonl, ntohs, uint8_t*
shortcuts: ← prev · → next · M mark
1
Little vs Big
x86 and ARM are little-endian; network byte order is big-endian.
0x12345678 little-endian
| addr | byte |
|---|---|
| +0 | 78 |
| +1 | 56 |
| +2 | 34 |
| +3 | 12 |
0x12345678 big-endian
| addr | byte |
|---|---|
| +0 | 12 |
| +1 | 34 |
| +2 | 56 |
| +3 | 78 |
Same value in a register, opposite layout in memory.
2
Detecting It
Inspect the first byte of a known value.
Example
example
uint32_t v = 1;
if (*(uint8_t*)&v == 1) puts("little-endian");
else puts("big-endian");3
Network Byte Order
Convert before you send, convert after you receive.
Example
example
#include <arpa/inet.h>
uint32_t on_wire = htonl(value); // host -> network
uint32_t local = ntohl(on_wire); // network -> host
uint16_t port = htons(8080);4
Serialization Rule
Never memcpy a struct onto the wire or into a file.
Common pitfalls
- ✕Struct padding differs between compilers and architectures.
- ✕Endianness differs between sender and receiver.
- ✕Type sizes (long) differ between 32- and 64-bit builds.
- ✕Serialize field by field with explicit widths and byte order instead.