P99

◆ P99_GENERIC

#define P99_GENERIC (   ...)

Type generic expression in anticipation of C11 _Generic.

This macro expects a syntax that is similar to that of C11's _Generic keyword. The syntax that we support is as follows

, // empty default expression
(int*, a),
(double*, x));

That is an expression EXP, followed by a default value DEF, followed by a list of type value pairs. So here this is an expression that depending on the type of a will have a type of int* or double* that will be set to a or x, respectively.

In C11 syntax, the above would be coded with some kind of "label" syntax:

_Generic(a,
int*: a,
double*: x);

As you can see above, the default value can be omitted. If omitted, it is replaced with some appropriate expression that should usually give you a syntax error.

If there is a default expression, it is used when none of the types matches:

a = P99_GENERIC(a + b,
max_uintmax,
(int, max_int),
(long, max_long),
(long long, max_llong),
(float, max_float),
(double, max_double))(a, b);

In C11 syntax

a = _Generic(a + b,
default: max_uintmax,
int: max_int,
long: max_long,
long long: max_llong,
float: max_float,
double: max_double)(a, b);

Here all of the expressions evaluate to a function specifier. If a + b is int, ... or double the appropriate maximum function is choosen for that type. If none of these matches, the one for uintmax_t is choosen. The corresponding function is then evaluated with a and b as arguments.

  • because the choice expression is a + b its type is the promoted common type of a and b. E.g for all types that are narrower than int, e.g short, normally int will be the type of the expression and max_int will be the function. If a is unsigned and b is double the result is also double.
  • the return type of the _Generic expression is a function to two arguments. If it is int, e.g, the type is int ()(int, int). So the return type of the function call would be int in that case.
  • the arguments are promoted and converted to the expected type of the choosen function
Remarks
If the compiler is C11 compliant, the P99_GENERIC expression will just be translated to the corresponding _Generic expression.
Otherwise only gcc and compatible compilers are supported.

Definition at line 699 of file p99_generic.h.