From mboxrd@z Thu Jan 1 00:00:00 1970 From: "Joseph S. Myers" To: gcc@gcc.gnu.org, libc-alpha@sourceware.cygnus.com Subject: Implementation of Date: Fri, 28 Jul 2000 12:47:00 -0000 Message-id: X-SW-Source: 2000-07/msg00950.html glibc implements C99 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 when it sees a call to __builtin_tgmath_unary_real_only. -- Joseph S. Myers jsm28@cam.ac.uk