P99

◆ P99_GEN_EXPR

#define P99_GEN_EXPR (   BASE,
  EXPR,
  ... 
)

Produce a type generic expression that can be used as if it were an inline function.

The motivation for declaring a macro that uses this is for expressions that evaluate their arguments multiple times.

E.g to define a macro P99_GEN_MAX you can use the following

(p00_a >= p00_b) ? p00_a : p00_b,
p00_a, p00_b),
b, c, hh, uhh, h, uh, i, u, l, ul, ll, ull,
d, f, ld
);
#define P99_GEN_MAX(A, B) \
P99_GEN_EXPR(maximum, ((A) >= (B)) ? (A) : (B), \
b, c, hh, uhh, h, uh, i, u, l, ul, ll, ull, \
d, f, ld \
) \
((A), (B))

This first defines 15 inline functions for the different arithmetic types, you could also just use P99_STD_ARITHMETIC_EXTS to produce that long list. Then the definition of the macro expands to a type generic expression that has as EXPR as its selection expression (here (A) >= (B)) ? (A) : (B)).

Remarks
the sole effect of using exactly the target expression for EXPR is that the type of the selection expression undergoes exactly the promotion or conversion rules that would be applied to EXPR if it were to be evaluated directly.

So, staying with the example above, we would have

int f(toto t);
double d;
double dd = P99_GEN_MAX(f(t), d);

the commonly used type of f and d for the evaluation of P99_GEN_MAX(f(t), d) would be double. Before computing the maximum value, the result of f(t) is converted to double and then the result of the operation is also double.

As you can already see from this simple example, for such an expression it is crucial that f(t) is only evaluated once, which is the principal goal of P99_GEN_EXPR.

Here is another example that shows how simple it is to produce the type generic math macros that should normally be provided by "tgmath.h".

#define p00_gen_sind sin
#define p00_gen_sinf sinf
#define p00_gen_sinld sinl
#define p00_gen_sindc csin
#define p00_gen_sinfc csinf
#define p00_gen_sinldc csinl
#define P99_GEN_SIN(A) P99_GEN_EXPR(sin, (A), P99_STD_FLOATING_EXTS)(A)

Definition at line 1000 of file p99_generic.h.

f
f
Definition: p99_str.h:138
ld
ld
Definition: p99_str.h:138
P99_GEN_MAX
#define P99_GEN_MAX(A, B)
Definition: p99_generic.h:1002
P99_DECLARE_INLINE_EXPRESSIONS
#define P99_DECLARE_INLINE_EXPRESSIONS(NEPL,...)
Declare a whole bunch of inline functions of basename BASE for expression EXP, applied to the builtin...
Definition: p99_generic.h:926
d
d
Definition: p99_str.h:138
i
P00_CLAUSE2 i(_Pragma("weak p00_getopt_comp"))(_Pragma("weak p00_getopt_comp