June 26, 2025 nullprogram.com/blog/2025/06/26/ C23 has a new rule for struct, union, and enum compatibility finally appearing in compilers starting with GCC 15, released this past April, and Clang later this year. The same struct defined in different translation units (TU) has always been compatible — essential to how they work. Until this rule change, each such definition within a TU was a distinct, incompatible type. The new rule says that, ackshually, they are compatible! This unlocks some type parameterization using macros. How can a TU have multiple definitions of a struct? Scope. Prior to C23 this wouldn’t compile because the compound literal type and the return type were distinct types: struct Example { int x, y, z; }; struct Example example(void) { struct Example { int x, y, z; }; return (struct Example){1, 2, 3}; } Otherwise the definition of struct Example within example was fine, if strange. At first this may not seem like a big deal, but let’s revisit my technique for dynamic arrays: typedef struct { T *data; ptrdiff_t len; ptrdiff_t cap; } SliceT; Where I write out one of these for each T that I might want to put into a slice. With the new rule we can change it slightly, taking note of the introduction of a tag (the name after struct): #define Slice(T) \ struct Slice##T { \ T *data; \ ptrdiff_t len; \ ptrdiff_t cap; \ } This makes the “write it out ahead of time” thing simpler, but with the new rule we can skip the “ahead of time” part and conjure slice types on demand. Each declaration with the same T is compatible with the others due to matching tags and fields. So, for example, with this macro we can declare functions using slices parameterized for different element types. Slice(int) range(int, Arena *); float mean(Slice(float)); Slice(Str) split(Str, char delim, Arena *); Str join(Slice(Str), char delim, Arena *); Or using it with our model parser: typedef struct { float x, y, z; } Vec3; typedef struct { int32_t v[3]; int32_t n[3]; } Face; typedef s...
First seen: 2025-06-27 08:26
Last seen: 2025-06-27 11:26