Выбор по типу: _Generic

Изменения в новых версиях / C11

// *** before: ***
//C99: one function per type, and the caller had to pick the right one;
//abs on a double quietly cut the fraction off
int wholeOld = abs(-7);
double rightOld = fabs(-2.5);
double wrongOld = abs(-2.5);        //the double became the int -2 first
//wrongOld is 2

printf("wrongOld is %g\n", wrongOld);

// *** in version C11: ***
//_Generic picks a branch by the type of the expression while compiling;
//<tgmath.h> did the same in C99, but only inside the library
#define absolute(x) _Generic((x), int: abs, long: labs, double: fabs)(x)
#define typeName(x) _Generic((x), int: "int", double: "double", \
                                  char *: "char *", default: "other")

double right = absolute(-2.5);
int whole = absolute(-7);
//right is 2.5
//whole is 7
//typeName(right) is "double"

printf("right is %g\n", right);
printf("whole is %d\n", whole);
printf("typeName(right) is %s\n", typeName(right));