← Mon, Oct 5 digest

Type Safe Generic Data Structures in C (2025)

read article ↗ hn thread ↗

Daniel Chase Hooper demonstrates a technique using unions and ternary expressions in macros to enforce compile-time type safety for generic data structures in C.

read it The article provides a clever, portable C macro trick for compile-time type checking without relying on void pointers or C++ features.

summary

The author explores implementing type-safe generic data structures in C without resorting to duplicate code generation via header re-inclusion or unsafe void pointers with dual allocations. By utilizing a union with a parameterized payload member and a ternary expression macro trick, the compiler enforces type safety at compile time and calculates sizes automatically. This approach avoids extra memory overhead and binary bloat while maintaining standard C compatibility. The technique scales cleanly to complex data structures like hash maps.

key points

  1. Using a union with a dummy payload member provides compile-time type information without consuming any runtime memory.
  2. The ternary expression macro trick forces compiler type checking against the expected type and gets optimized away completely.
  3. Flexible array members combine the node and data into a single allocation to improve cache locality over separate pointer allocations.

who should read it

Systems programmers and C developers looking for clean ways to implement type-safe generics without moving to C++ or Rust.

discussion mixed

consensus

Most commenters debate whether complex macro engineering in C is worth avoiding C++ or Rust. While some appreciate the cleverness of the compiler tricks, many question why developers go to such lengths instead of using a language with native generics.

pushback

A minority argue that C++'s object lifetime rules and standard library overhead justify avoiding it entirely in strict systems contexts.

best comment by tniemi ↗

That `(1 ? (item) : (list)->payload)` was a neat trick. It gets optimized away, but the type comparison happens before that.

Still feels a bit like a party trick, but if it works...

It analyzes the core ternary expression trick used in the article and confirms how it behaves during optimization.

Generated by an LLM from the article and thread. Check the sources before relying on it.