pointers-memory · advanced · ~15 min

Tagged Pointer Alignment Encoder

Understand memory alignment and implement tagged pointer compression techniques.

Challenge

Pointers to heap structures aligned on 8-byte boundaries always have their lowest 3 bits set to 000. Tagged pointer architectures exploit this alignment to pack type tags (such as integer vs pointer vs float) into the lowest bits without allocating extra metadata.

Your Task

Given the 2-bit tag type:

typedef enum {
    TAG_RAW_PTR = 0, // bits 00
    TAG_STRING  = 1, // bits 01
    TAG_INT_OBJ = 2, // bits 10
    TAG_FLOAT   = 3  // bits 11
} PointerTag;

Implement tagged pointer packing:

uintptr_t tag_pointer(const void *ptr, PointerTag tag);
void *untag_pointer(uintptr_t tagged);
PointerTag get_pointer_tag(uintptr_t tagged);

Rules

  1. In tag_pointer:
    • Cast ptr to uintptr_t.
    • If ((uintptr_t)ptr & 0x03) != 0, return 0 (alignment violation: pointer is not 4-byte aligned).
    • Encode tag (which is 0..3) into the lowest 2 bits: ((uintptr_t)ptr) | (tag & 0x03).
    • Return the tagged integer.
  2. In untag_pointer:
    • Clear the lowest 2 bits: tagged & ~((uintptr_t)0x03).
    • Cast back to void * and return it.
  3. In get_pointer_tag:
    • Return (PointerTag)(tagged & 0x03).

Example

int x = 42; // assume aligned at 0x1000
uintptr_t t = tag_pointer(&x, TAG_STRING); // 0x1001
get_pointer_tag(t); // returns TAG_STRING
untag_pointer(t); // returns &x (0x1000)

Input format

ptr: pointer to align; tag: PointerTag enum; tagged: uintptr_t encoded value.

Output format

Returns encoded uintptr_t, decoded pointer, or extracted PointerTag.

Constraints

Pointers must be at least 4-byte aligned (& 0x03 == 0). Use uintptr_t.

Starter code

#include <stdint.h>

typedef enum {
    TAG_RAW_PTR = 0,
    TAG_STRING  = 1,
    TAG_INT_OBJ = 2,
    TAG_FLOAT   = 3
} PointerTag;

uintptr_t tag_pointer(const void *ptr, PointerTag tag) {
    (void)ptr; (void)tag;
    return 0;
}
void *untag_pointer(uintptr_t tagged) {
    (void)tagged;
    return 0;
}
PointerTag get_pointer_tag(uintptr_t tagged) {
    (void)tagged;
    return TAG_RAW_PTR;
}

Common mistakes

Casting pointer to int instead of uintptr_t (64-bit truncation); sign-extension issues with masks.

Edge cases to handle

Unaligned pointer returns 0 on tag_pointer; NULL pointer with tag can be encoded and untagged back to NULL.

Background lessons

Solve this exercise in the browser editor — compile and run against the test harness, no setup required.