typestar

offsetof and layout in C

offsetof reports where a member sits, which is how intrusive containers work.

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

typedef struct {
    int id;
    char label[8];
    double score;
} Record;

#define CONTAINER_OF(ptr, type, member) \
    ((type *) ((char *) (ptr) - offsetof(type, member)))

void layout(void) {
    Record r = {7, "step", 91.5};
    double *score = &r.score;
    Record *back = CONTAINER_OF(score, Record, score);

    printf("%zu %zu %zu\n", offsetof(Record, id),
           offsetof(Record, label), offsetof(Record, score));
    printf("recovered id %d\n", back->id);
}

How it works

  1. It yields a size_t byte offset from the struct's start.
  2. Subtracting it from a member address recovers the struct.
  3. That is the trick behind the container_of macro.

Keywords and builtins used here

The run, in numbers

Lines
21
Characters to type
466
Tokens
111
Three-star pace
100 tpm

At the three-star pace of 100 tokens a minute, this run takes about 67 seconds.

Type this snippet

Step 4 of 5 in Unions & layout, step 4 of 13 in Unions, bitfields & undefined behavior.

← Previous Next →