Post #2813120
2026-05-12 07:39 UTC
@erisceleste@tech.lgbt @thephd@pony.social unfortunately, nesting Generics brings us back to the original problem, that even the unselected branches have to be semantically valid, so that if you want to accept types (T,T), (T,U), and (U,T), but not (U,U), then you're in trouble, because the sub-Generic in the (U,x) branch which has no case for x=U will fail when you pass types (T,U) to select the other branch.
I suppose it's true that if it's feasible to write each branch of the doubly-switched Generic in the form of a function, then you can use the typeof trick to switch between those functions, in the good old-fashioned style of only selecting the function name:
inline void foo_ii(int a, int b) { /* ... */ }
inline void foo_ip(int a, char *b) { /* ... */ }
inline void foo_pi(char *a, int b) { /* ... */ }
# define foo(x, y) _Generic( (void (*)(typeof(x), typeof(y)))NULL,
void (*)(int, int): foo_ii,
void (*)(int, char *): foo_ip,
void (*)(char *, int): foo_pi) (x, y)
and then you do get both a non-orthogonal set of type pairs, and an identifier for each of the two things at the point of actually using them (in the body of each function).
Replies (1)
-
@uecker@mastodon.social 2026-05-12 17:31
@simontatham@hachyderm.io @erisceleste@tech.lgbt @thephd@pony.social I think you want to switch on a pair type. Still needs hacks though. https://godbolt.org/z/TGfefnYfM