Date: Fri, 9 Mar 2012 22:28:44 -0500 From: Rich Felker <dalias@...ifal.cx> To: musl@...ts.openwall.com Subject: Re: libm On Fri, Mar 09, 2012 at 12:02:54PM -0500, Rich Felker wrote: > On Fri, Mar 09, 2012 at 10:56:55AM -0500, Rich Felker wrote: > > > > Then add __RETCAST((x)), __RETCAST((x)+(y)), etc. Some trick will be > > > > needed to make integer types result in a cast to double, though. > > > > > > hm the int->double and complex/real cases are tricky > > > > > > i thought +1.0 or +I would solve these, but that's wrong > > > > I think +0.0f might solve it. Isn't the promoted type of any integer > > type with float double? > > Nope, it results in float. glibc has a trick involving obscure > interactions of null pointer constants and the ?: operator that > generates the right type using __typeof__, which is no big deal > because this code is already only used when __typeof__ is available, > anyway. > > There's a good blog article on it somewhere which I can't seem to find > at the moment... Try this: #define __RETCAST(x) (__typeof__(*(0 \ ? (__typeof__(0 ? (double *)0 : (void *)__IS_FP(x)))0 \ : (__typeof__(0 ? (__typeof__(x) *)0 : (void *)!__IS_FP(x)))0 ))) In the outer conditional operator, the second operand is a pointer to double if (void *)__IS_FP(x) is a null pointer constant (which is true iff __IS_FP(x)==0) and otherwise is a pointer to void. Conversely, the third operand of the outer conditional is a pointer to __typeof__(x) iff __IS_FP(x)!=0, and otherwise a pointer to void. Thus the outer conditional sees either "double *" and "void *", or else "void *" and "__typeof__(x) *", resulting it in having type "double *" or "__typeof__(x)", reflecting whether x was an integer or floating point type. Rich
Powered by blists - more mailing lists
Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.