Endianness
int, long, pointers, and so on — since a single char has no ordering to speak of.Big-Endian vs Little-Endian
Term | Byte order | Used by |
|---|---|---|
Little-endian | Least significant byte stored first (lowest address) | x86, x86-64, and most ARM configurations -- i.e. almost every desktop, laptop, and phone |
Big-endian | Most significant byte stored first (lowest address) | Some older architectures (SPARC, older PowerPC), and network protocols by convention |
The Same Integer, Two Memory Layouts
0x12345678. In memory, its four bytes are ordered completely differently depending on the machine:Value: 0x12345678 Little-endian memory layout (address increasing left to right): [0x78] [0x56] [0x34] [0x12] Big-endian memory layout (address increasing left to right): [0x12] [0x34] [0x56] [0x78]
You can observe this directly in C:
#include <stdio.h>
#include <stdint.h>
int main(void) {
uint32_t value = 0x12345678;
unsigned char *bytes = (unsigned char *)&value;
for (int i = 0; i < 4; i++) {
printf("byte[%d] = 0x%02x\n", i, bytes[i]);
}
return 0;
}// On a little-endian machine (e.g. x86-64): byte[0] = 0x78 byte[1] = 0x56 byte[2] = 0x34 byte[3] = 0x12
Why It Matters
Network protocols -- TCP/IP headers define a fixed "network byte order," which is big-endian, regardless of the sender or receiver's native endianness
Binary file formats shared across machines -- a file written on a little-endian machine and read on a big-endian one will misinterpret multi-byte fields unless the format explicitly documents (and the reader respects) a byte order
Interop with hardware or protocols that mandate a specific byte order (many file formats, some sensors, cryptographic primitives)
Byte-Order Conversion Functions
<arpa/inet.h> on POSIX systems) provides a family of conversion functions that translate between a host's native byte order and network byte order:uint32_t htonl(uint32_t hostlong); // host to network, 32-bit ("long")
uint16_t htons(uint16_t hostshort); // host to network, 16-bit ("short")
uint32_t ntohl(uint32_t netlong); // network to host, 32-bit
uint16_t ntohs(uint16_t netshort); // network to host, 16-bit#ifdef for endianness.