This is the mail archive of the libc-alpha@sources.redhat.com mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Implementation of <tgmath.h>


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]