P99
#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

 P99_GENERIC(a,
             , // 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 so, it is replaced with some appropriate expression that should usually give you a syntax error.

If there is a default expression, that one 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 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 would be unsigned and b would be double the result would be double, too.
  • the return type of the _Generic expression is a function to two arguments. If it would be for int, e.g, the type would be 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 complying, the P99_GENERIC expression will just be translated to the corresponding _Generic expression.
Otherwise only gcc and compatible compilers are supported.

Definition at line 442 of file p99_generic.h.

 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Defines