Date: Sat, 10 Mar 2012 13:45:53 +0100 From: Szabolcs Nagy <nsz@...t70.net> To: musl@...ts.openwall.com Subject: Re: libm * Rich Felker <dalias@...ifal.cx> [2012-03-09 22:28:44 -0500]: > 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. > of course there was another twist: some complex functions return real value :) i solved that with a __TO_REAL(x) macro using similar tricks so __RETCAST(__TO_REAL(x)) gives correct return type there are two remaining problems: for two argument functions __RETCAST((x)+(y)) is not ok if x is float, y is int then the return type should be double, not float (this can be solved by a __RETCAST2(x,y) i guess) if sizeof(long double) == sizeof(double) then the selected function will be wrong (it should not matter much, we can leave it as is or enforce double)
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.