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 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 623 of file p99_generic.h.

 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Defines