Implementation of <tgmath.h>

Joseph S. Myers jsm28@cam.ac.uk
Fri Jul 28 12:47:00 GMT 2000


glibc implements C99 <tgmath.h> using statement expressions and
__typeof__, and at first glance it appears that these extensions are
necessary and sufficient for the implementation.  However, closer
examination shows they are not sufficient to get the spec right.  Consider
for example the simplest of the definitions,

# define __TGMATH_UNARY_REAL_ONLY(Val, Fct) \
     (__extension__ ({ __typeof__(Val) __tgmres;                   \
                       if (sizeof (Val) == sizeof (double))        \
                         __tgmres = Fct(Val);                      \
                       else if (sizeof (Val) == sizeof (float)     \
                         __tgmres = Fct##f (Val);                  \
                       else                                        \
                         __tgmres = Fct##l (Val);                  \
                       __tgmres; }))

The standard requires the function invoked by the macro to be chosen as
follows: the `long double' function if the argument is long double, the
`double' function if the argument is double or of integer type, or else
the `float' function.  The macro used in glibc will yield the wrong
results for integer arguments; the wrong function may be chosen, depending
on the integer type, and the result will be wrongly converted to the
integer type, instead of remaining a double.  I don't see any way of fully
fixing this within the scope of the present GCC extensions.  (Using
__typeof__((Val) + 0.0F) would be closer to correct, but still wrong since
integer types count as double rather than float.)  The best suggestion I
have for a compiler extension to allow a correct implementation would be a
series of builtin functions corresponding to the glibc macros, so that for
example

#define expm1(Val) __builtin_tgmath_unary_real_only(Val, expm1f, expm1, \
						    expm1l)

would have the compiler create a call to the appropriate one of expm1f,
expm1, expm1l according to the type of Val and the rules of <tgmath.h>
when it sees a call to __builtin_tgmath_unary_real_only.

-- 
Joseph S. Myers
jsm28@cam.ac.uk



More information about the Libc-alpha mailing list