_Generic(3)
π _Generic β type-generic selection β¨
okay bestie, listen up, because this one is genuinely iconic. the manual name is _Generic(3) and it lives in the Library Functions Manual, and it is lowkey one of the most underrated little tricks in all of C. π«Ά
β¨ SYNOPSIS β¨
_Generic(expression, type1: e1, ... /*, default: e */);
that's it. that's the whole vow. π
πΈ DESCRIPTION πΈ
so here's the tea: _Generic() walks down the list of type selectors and evaluates the one code path that sits under whichever type is compatible with the type of the controlling expression. and if literally nothing matches? it falls back to default: instead. mwah, chef's kiss. π
and now the part that makes everyone gasp: expression is not evaluated. nope, not even a little. it's giving "vibe check only, no touching". π
the way that this is especially useful is for writing type-generic macros β macros that get to act all different depending on the type of the argument you hand them. main character behaviour, honestly. π
β STANDARDS β
C11. that's the standard, bestie. no notes. π
π¦ HISTORY π¦
C11. it came in with the standard, it's been slaying ever since. periodt. π
π EXAMPLES π
okay so here's a whole little program that shows you how to write your own replacement for the standard imaxabs(3) function. and here's the drama: imaxabs(3) is a function, so it can't actually deliver what it promises β namely, seamlessly upgrading to the widest available type. it simply cannot do it. the audacity, honestly. π
so we do it ourselves with _Generic, like this:
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#define my_imaxabs _Generic(INTMAX_C(0), \
long: labs, \
long long: llabs \
/* long long long: lllabs */ \
)
int
main(void)
{
off_t a;
a = -42;
printf("imaxabs(%jd) == %jd\n", (intmax_t) a, my_imaxabs(a));
printf("&imaxabs == %p\n", &my_imaxabs);
printf("&labs == %p\n", &labs);
printf("&llabs == %p\n", &llabs);
exit(EXIT_SUCCESS);
}
look at her go. selecting labs or llabs at compile time depending on which type gets picked, printing pointers to both of them and to the macro itself. obsessed. π₯
ngl the commented-out /* long long long: lllabs */ line is a little easter egg of longing for a type that does not exist. we've all been there. π
π SEE ALSO π
no extra cross-references on this page, bestie β the imaxabs(3) shoutout above is the one doing all the heavy lifting. π
anyway, that's the whole page. this was Linux man-pages 6.20, dated 2025-05-17 β thanks for coming to my ted talk, ily, go write a type-generic macro, you're gonna eat. π«Άβ¨π
π¦ where this page comes from
- arch rolling: man-pages 6.20-1 Β· BSD-2-Clause AND BSD-3-Clause AND BSD-4.3TAHOE AND BSD-4-Clause-UC AND GPL-1.0-or-later AND GPL-2.0-only AND GPL-2.0-or-later AND GPL-3.0-or-later AND LGPL-3.0-linking-exception AND LGPL-3.0-or-later AND LicenseRef-Public-Domain AND LicenseRef-UltraPermissive AND Linux-man-pages-1-para AND Linux-man-pages-copyleft AND Linux-man-pages-copyleft-2-para AND Linux-man-pages-copyleft-var AND MIT AND Spencer-94
- nixpkgs unstable: man-pages 6.20
- π the page's license: Linux-man-pages-copyleft
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms