Skip to content
  • Padding & Alignment · C

Padding & Alignment

LearnViaNotes @learnvianotes· 3 min read

CPUs load data fastest (or only) at addresses that are multiples of its size. The compiler therefore inserts invisible padding bytes into structs, so sizeof is often larger than the sum of the members.

C
#include <stdio.h>
#include <stddef.h>

struct Bad  { char a; int b; char c; };      /* 1 + 3 pad + 4 + 1 + 3 pad */
struct Good { int b; char a; char c; };      /* 4 + 1 + 1 + 2 pad */

int main(void) {
    printf("Bad  = %zu bytes\n", sizeof(struct Bad));
    printf("Good = %zu bytes\n", sizeof(struct Good));
    printf("offsets in Bad: a=%zu b=%zu c=%zu\n",
           offsetof(struct Bad, a), offsetof(struct Bad, b), offsetof(struct Bad, c));
    printf("alignof(int)=%zu alignof(double)=%zu\n", _Alignof(int), _Alignof(double));
    return 0;
}
Output
Bad  = 12 bytes
Good = 8 bytes
offsets in Bad: a=0 b=4 c=8
alignof(int)=4 alignof(double)=8

The rules

  1. Each member is aligned

    A member of type T starts at an offset that is a multiple of _Alignof(T) — padding is inserted before it if needed.

  2. The struct is aligned

    The struct’s alignment is the largest alignment of any member.

  3. Tail padding

    sizeof is rounded up to a multiple of the struct’s alignment, so that in an array every element is aligned too.

  4. Order is kept

    The compiler never reorders members — the first member is always at offset 0.

Offset01234–789–11
struct Badapadpadpadbcpad

Minimising padding

C
#include <stdio.h>

struct Messy  { char c1; double d; char c2; int i; short s; };
struct Sorted { double d; int i; short s; char c1; char c2; };   /* largest first */

int main(void) {
    printf("%zu %zu\n", sizeof(struct Messy), sizeof(struct Sorted));
    return 0;
}
Output
32 16

Packing (compiler extension)

C
#include <stdio.h>
#include <stdint.h>

struct __attribute__((packed)) Header {     /* GCC/Clang; MSVC uses #pragma pack(1) */
    uint8_t  type;
    uint32_t length;
    uint16_t flags;
};

int main(void) {
    printf("packed size = %zu\n", sizeof(struct Header));
    return 0;
}
Output
packed size = 7

Explicit alignment (C11)

C
#include <stdio.h>
#include <stdalign.h>
#include <stdint.h>

struct Cacheline { alignas(64) char data[64]; };   /* avoid false sharing between threads */

int main(void) {
    alignas(16) float v[4] = {0};
    printf("%zu %zu %d\n", alignof(struct Cacheline), sizeof(struct Cacheline),
           (int)((uintptr_t)v % 16 == 0));
    return 0;
}
Output
64 64 1

What is structure padding and why does it exist?

What is sizeof(struct { char c; double d; })?

How do you find the offset of a member?

Free for students and teachers

Write notes like this one

Cards for every idea, quizzes and flashcards, read aloud — on the web and your phone.

Something wrong with this note? Open it to report