type-generic math (<tgmath.h>)
/ TEE-jee-math /
In C, sqrt() works on a double, sqrtf() on a float, and sqrtl() on a long double. Writing the right suffix every time is tedious and easy to get wrong, especially when you later change a variable's type. The header <tgmath.h> gives you ONE name, sqrt(x), that automatically routes to the correct sized function based on the type of x.
Under the hood, <tgmath.h> defines macros (not functions) named like the plain math functions. Each macro uses _Generic-style type dispatch on its argument: if x is float it expands to sqrtf, if double to sqrt, if long double to sqrtl, and it also handles the complex versions (csqrt and friends) from <complex.h>. So including <tgmath.h> shadows the ordinary names from <math.h> and <complex.h> with these dispatching macros. The effect is that math code becomes type-portable: change x from double to float and every call follows along.
It matters for numeric and scientific code where you want to write an algorithm once and instantiate it at several precisions. The honest caveat: because these are macros, you cannot take the address of sqrt under <tgmath.h>, the argument may be textually substituted in a way that surprises you, and error messages get worse. Also, integer arguments are promoted to double (so sqrt(2) calls the double version), which is usually what you want but worth knowing.
#include <tgmath.h> float f = 2.0f; double d = 2.0; float rf = sqrt(f); // expands to sqrtf(f) double rd = sqrt(d); // expands to sqrt(d)
One spelling, sqrt, that picks sqrtf or sqrt by the argument's type — that routing is _Generic at work.
These are macros, not functions: &sqrt under <tgmath.h> does not name a function, and the argument can be evaluated or substituted in surprising ways, so avoid side effects in tgmath arguments.