C Mastery / Endianness and Alignment at the Hardware Level
Part 7 — CPU Architecture and Assembly

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

Core Concept

Endianness

A multi-byte integer is stored in consecutive bytes. The order is either:

ARM in practice).

protocols, some embedded SoCs).

For 0x01020304 at address A:

AddressLittle-endianBig-endian
A0x040x01
A+10x030x02
A+20x020x03
A+30x010x04

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

reader shares the same endianness.

parts can be big-endian).

Undefined Behavior

aliasing) — use unsigned char or memcpy.

Portability

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

network/file data.

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.

References

Verification

verified.`

Progress

Concept checkboxes

Mastery levels

ConceptCurrent level (0–8)Target level
c.cpu.endianness06
c.cpu.alignment06