This is the mail archive of the
libc-help@sourceware.org
mailing list for the glibc project.
Re: isinf oddity
- From: OndÅej BÃlka <neleai at seznam dot cz>
- To: Carlos O'Donell <carlos at redhat dot com>
- Cc: Wilco Dijkstra <wdijkstr at arm dot com>, libc-help at sourceware dot org, Roland McGrath <roland at hack dot frob dot com>
- Date: Fri, 28 Nov 2014 21:40:32 +0100
- Subject: Re: isinf oddity
- Authentication-results: sourceware.org; auth=none
- References: <000101d00b0c$2eada770$8c08f650$ at com> <5478D019 dot 7010400 at redhat dot com>
On Fri, Nov 28, 2014 at 02:42:17PM -0500, Carlos O'Donell wrote:
> On 11/28/2014 08:06 AM, Wilco Dijkstra wrote:
> > Hi,
> >
> > I noticed there is something odd with the definition of isinf in GLIBC: it returns the sign of the
> > infinity in the result. This is bad as neither C99 nor C++11 define this, so any software written to
> > take advantage of this will silently fail when a conforming implementation is used. Checking for the
> > sign of an infinity is rarely needed, and it is even rarer to be performance critical. A grep
> > through GLIBC revealed only a few uses in the printf code - all of which could be trivially fixed.
> > It also means we could remove the __isinf_ns(f/l) variant and make it the default as this version is
> > C99/C++11 conforming and is simpler/faster as a bonus.
>
A problem is that its documented behavior, we write that in manual and
in manpage, breaking existing software is would be more serious problem
than trying to force portability where it was probably already detected
on another platform.
> How much faster? Could you add a microbenchmark for isinf for
> all supported types and measure? See glibc/benchtests/README.
>
> The fact that you stand to make it faster for standards
> conforming applications is the only reason we might make
> some kind of change.
>
> Without performance numbers the present implementation meets
> the requirements of the standard and is documented in the
> glibc manual.
>
That is tricky as you know what to benchmark.
One is just do loop like
int i = 0;
float f;
for (f = 0.0; f < 100000.0; f+= 0.3)
i += isinf (f);
Second one is notice that often isinf is used in condition so you could
write:
int i = 0;
float f;
for (f = 0.0; f < 100000.0; f+= 0.3)
if (isinf (f))
i++:
else
printf ("cannot happen");
These two approaches give different result. In particular it does not
matter if we return nonzero or +-1 as it condition if (isinf(x)) gets expanded to
if ((foo (x) ? (bar (x) ? 1 : -1) : 0))
and gcc will simplify that into
if (foo (x))