Endianness and Alignment at the Hardware Level
This chapter explains endianness (byte order) and alignment as hardware properties, and how they surface in C code.
Why This Matters
Byte order determines how multi-byte integers are stored in memory, which matters for network protocols, file formats, and FFI. Alignment determines where objects may live and whether a pointer access is valid. Both are frequent sources of subtle portability bugs.
Prerequisites
c.cpu.1— CPU registers and memory access.
Core Concept
Endianness
A multi-byte integer is stored in consecutive bytes. The order is either:
- Little-endian: least significant byte at the lowest address (x86, most
ARM in practice).
- Big-endian: most significant byte at the lowest address (some network
protocols, some embedded SoCs).
For 0x01020304 at address A:
| Address | Little-endian | Big-endian |
|---|---|---|
| A | 0x04 | 0x01 |
| A+1 | 0x03 | 0x02 |
| A+2 | 0x02 | 0x03 |
| A+3 | 0x01 | 0x04 |
Alignment
An object of type T must be stored at an address divisible by its alignment (_Alignof(T)). Misaligned access is UB in C, and on some hardware it faults or is very slow.
Examples
Detecting endianness at run time (portably enough)
#include <stdint.h>
#include <stdio.h>
int main(void)
{
uint16_t x = 0x0102;
unsigned char *b = (unsigned char *)&x;
if (b[0] == 0x02)
puts("little-endian");
else
puts("big-endian");
return 0;
}
Reading the representation through unsigned char is well-defined.
Alignment demonstration
#include <stdio.h>
#include <stdalign.h>
int main(void)
{
printf("alignof(int) = %zu\n", alignof(int));
printf("alignof(double)= %zu\n", alignof(double));
return 0;
}
How It Works
Endianness is a property of how the CPU stores/loads multi-byte values. Alignment is a hardware constraint: the CPU loads aligned words efficiently (or at all). The C compiler honors the platform's alignment by padding structs and aligning stack/heap objects.
Variations
Network byte order
Network protocols conventionally use big-endian ("network byte order"), which is why htons/ntohl conversions exist (c.net.4).
Bi-endian
Some architectures can switch endianness (e.g., ARM in some modes), but a given process is one or the other.
Common Mistakes
- Writing multi-byte integers directly to a file or socket and assuming the
reader shares the same endianness.
- Dereferencing a pointer cast to a wider type from an unaligned byte buffer.
- Assuming all ARM is little-endian (it is configurable; network/embedded
parts can be big-endian).
Undefined Behavior
- Dereferencing a misaligned pointer.
VERIFIED - Reading a multi-byte value through an lvalue of an incompatible type (strict
aliasing) — use unsigned char or memcpy.
Portability
- Endianness is implementation-defined (hardware). Alignment is
implementation-defined. Use explicit byte-wise serialization for portability.
Under the Hood
Little-endian CPUs have byte-swap instructions (bswap on x86) for converting to/from network order. Misaligned loads are handled by hardware (x86, slowly) or fault (some ARM/RISC-V), or by the compiler via multiple byte loads.
Practical Usage
- Serialize integers byte-by-byte (or use explicit endian conversion) for
network/file data.
- Keep buffers aligned; use
memcpyto read unaligned data safely. - Use
htons/ntohl/htonl/ntohsfor network order.
Exercises
1. Write a program that detects your platform's endianness. 2. Convert a uint32_t to and from big-endian bytes using shifts. 3. Demonstrate that memcpy can safely read an unaligned int from a byte buffer.
Deep Challenge
Write a portable read_u32_be(const unsigned char *p) and read_u32_le that decode big-endian and little-endian integers from a byte buffer without alignment or aliasing UB, and explain why they are portable.
Related Concepts
c.net.4— byte order and endian conversion.c.obj.alignment— alignment.c.obj.representation— object representation.
References
- CPU architecture manuals; ISO C §6.2.6 (representations).
Verification
- Endianness and alignment are hardware/implementation-defined.
HARDWARE - Misaligned dereference is UB.
VERIFIED - No example was executed during generation unless noted. `Execution not
verified.`
Progress
- [ ] Read
- [ ] Understand
- [ ] Complete examples
- [ ] Complete exercises
- [ ] Complete deep challenge
Concept checkboxes
- [ ] Little vs. big endian
- [ ] Network byte order
- [ ] Hardware alignment
- [ ] Misaligned access UB
Mastery levels
| Concept | Current level (0–8) | Target level |
|---|---|---|
| c.cpu.endianness | 0 | 6 |
| c.cpu.alignment | 0 | 6 |