Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date: Sat, 10 Mar 2012 13:45:53 +0100
From: Szabolcs Nagy <>
Subject: Re: libm

* Rich Felker <> [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.