ISO/IEC 9899:1999(C99)で標準に追加されたヘッダーでは、引数の型に応じて対応する数学関数を呼び出す型総称マクロType-generic macrosが定義されます。
をインクルードすると、とが（暗黙に）インクルードされます。
C言語の数学関数には実数型と複素数型があります。それぞれ引数の型に応じて、float、double、long doubleの3種類があるので 2\times 3=6通りの組み合わせを生じます。
C言語はC++のようなオーバーロードをサポートしていないため、引数の型が異なる関数のバリエーションには { sin, sinf, sin, sinl, csinf, csin, csinl } のような名前が付けられています。
には、呼び出すべき正しい数学関数の選択を簡単にするマクロが含まれています。マクロは渡された型に応じて正しい関数を呼び出します。
例えば、マクロsqrt()では、sqrt(2.0f) は sqrtf(2.0f)を、sqrt(2.0) は sqrt() をマクロプロセッサは、マクロ展開の結果に再びマクロを適用することはしないのでマクロ名と展開先の関数名が一致している事は問題になりません。、sqrt(2.0L) ならば sqrtl(2.0L) を呼び出します。
[https://paiza.io/projects/ff4FsPGaoO64R1l2xboTXQ?language=c コード例]
int main(void)
{
  printf("%32.30f\n",  sqrt(2.0f));
  printf("%32.30f\n",  sqrt(2.0));
  printf("%32.30Lf\n", sqrt(2.0L));
  float complex f = 2 + I * 2;
  f = sqrt(f);
  printf("%32.30f+%32.30fi\n", creal(f), cimag(f));
  double complex d = 2 + I * 2;
  d = sqrt(d);
  printf("%32.30f+%32.30fi\n", creal(d), cimag(d));
  long double complex l = 2 + I * 2;
  l = sqrt(l);
  printf("%32.30Lf+%32.30Lfi\n", creal(l), cimag(l));
}
結果
1.414213538169860839843750000000
1.414213562373095145474621858739
1.414213562373095048763788073032
1.553773999214172363281250000000+0.643594264984130859375000000000i
1.553773974030037363647238635167+0.643594252905582586699040348321i
1.553773974030037307377145883169+0.643594252905582624700326493938i
ISO/IEC 9899:2011(C11)で、キーワード _Generic が導入されました。
_Generic は、型ジェネリック式を実現するためのもので、C++のオーバーロードの様に引数の型によって処理を選択します。
構文
 _Generic( 式, 型: 値, 型: 値, 型: 値,  ... 型: 値)
型ジェネリック式は、与えられた「式」と一致する型に対応した値を取ります。
特別な「型」として default があり、他の全ての型に一致しなかった場合に default に対応した値を取ります。
_Generic の使用例（C11：WG14/N1570 Committee Draft ISO/IEC.p.68, §6.5.1.1 ''Generic selection''.から抜粋）
                        long double: cbrtl,          \
                        default: cbrt,               \
                        float: cbrtf                 \
                        )(X)
crrt()は、立方根（cube root）を返す関数ですが、引数の種類によって、
     double cbrt(double x);
     float cbrtf(float x);
     long double cbrtl(long double x);
の3つのバリエーションがあります。
この例で示された型総称マクロcbrt()では、_Generic() で渡された仮引数 X によって呼び出す関数を切り替えています。
実際のプログラムで、このマクロを使って試してみましょう。
[https://paiza.io/projects/5SFrSFHrrjy0bWWP9eHtLQ?language=c コード例]
                        long double: cbrtl,          \
                        default: cbrt,               \
                        float: cbrtf                 \
                        )(X)
int main()
{
    printf("%32.30f\n",  cbrt(2.0f));
    printf("%32.30f\n",  cbrt(2.0));
    printf("%32.30Lf\n", cbrt(2.0L));
}
結果
1.259921073913574218750000000000
1.259921049894873190666544360283
1.259921049894873164754112437880