A generic selection is a primary expression. Its type and value depend on the selected generic association.
The following diagram shows the generic selection syntax:
.-,-----------------------------------------. V | >>-_Generic--(--assignment-expression--,----+-type-name--:--assignment-expression---+-+--)->< | (1) | '-default--:--assignment-expression-----'
One generic selection cannot have two or more generic associations that specify compatible types. In one generic selection, the controlling expression can have at most one compatible type name in the generic association list. If a generic selection has no default generic association, its controlling expression must have exactly one compatible type name in its generic association list.
If there is a generic association with a type name that is compatible with the controlling expression in the generic selection, the expression in the generic selection is the result expression. Otherwise, the result expression of the generic selection is the expression in the default generic association. The controlling expression of a generic selection is not evaluated. None of the expressions from any other generic association of the generic selection is evaluated.
The type and value of a generic selection are identical to those of its result expression. For example, a generic selection is an lvalue, a function designator, or a void expression if its result expression is an lvalue, a function designator, or a void expression.
#define myfunction(X) _Generic((X), \
long double:myfunction_longdouble, \
default:myfunction_double, \
float:myfunction_float \
)(X)
void myfunction_longdouble(long double x){printf("calling %s\n",__func__);}
void myfunction_double(double x){printf("calling %s\n",__func__);}
void myfunction_float(float x){printf("calling %s\n",__func__);}
int main()
{
long double ld;
double d;
float f;
myfunction(ld);
myfunction(d);
myfunction(f);
}
When you execute the program:xlc myprogram.c -qldbl128 -qlanglvl=extc1x
./a.out
the result is as follows:calling myfunction_longdouble
calling myfunction_double
calling myfunction_float