gcc-3.4.4-1: c++: cmath: calling std::isnan results in endless loop

Gregory Pietsch gpietsch@comcast.net
Mon Feb 27 19:53:00 GMT 2006


Dave Korn wrote:
> On 27 February 2006 14:40, Thomas Sailer wrote:
>
>   
>> When I try to call std::isnan(double) from a program compiled with g++
>> 3.4.4, the program gets into an endless loop.
>>
>> The problem is that gcc compiles
>> __gnu_cxx::isnan<double>(double) as a tail call to
>> __gnu_cxx::__capture_isnan<double>(double), and it compiles
>> __gnu_cxx::__capture_isnan<double>(double) to
>> __gnu_cxx::isnan<double>(double). It looks to me that this wrapping hack
>> (that is also in current glibc) only works if isnan is a macro. But on
>> cygwin, this isn't the case.
>>     
>
>   My first thought was that this was a libstdc++ bug and should be reported to
> them as such, that it was perhaps assuming that it would always be built with
> glibc and therefore assuming that it can know that isnan would be a macro.
> Cygwin OTOH is a newlib-based platform, and in our case isnan is not a macro.
> I believe that libstdc++ is meant to be independent of the underlying C
> library, and so it should either not make any assumption that may be invalid,
> or should detect (using autoconf tests) whether isnan is a macro or function
> on the target and adapt its behaviour to the actual circumstances.
>
>   Ah, this is something that appears to describe the mechanism that has gone
> wrong here:
> http://gcc.gnu.org/onlinedocs/libstdc++/17_intro/porting-howto.html#sec-macros
>
> " Glibc 2.0.x and 2.1.x define the <ctype.h>  -functionality as macros
> (isspace, isalpha etc.). Libstdc++-v3 "shadows" these macros as described in
> the section about c-headers."
>
>   However, even more interesting is that after browsing the spec, I found
> something surprising.  The float-type-classification isXXXXX definitions from
> math.h aren't like the isXXXXX character-type-classification functions.  The
> language spec says that functions like isprint, isspace, etc. may be
> implemented as macros.  But the fp-class symbols like isnan and isinf are
> defined by the standard as being macros and NOT functions.
>
>   It looks to me like the cygwin/newlib combination is not being compliant if
> it implements isnan as a function rather than a macro.  I couldn't see
> anything in the standard that says it can be a function, and every reference
> to it describes it as a macro, not a function.  It may be the case that
> libstdc++ is within its rights to assume that isnan is a macro after all.
>
>   OTOH it may be that libstdc++ was only supposed to be shadowing those ctype
> macros that are guaranteed to have underlying function implementations; I
> don't know what the shadowing is for, so I can't comment.
>
>   Hence this x-post to libstdc++ and newlib, where those-who-know can set us
> straight.
>
>     cheers,
>       DaveK
>   
The C99 standard has the math is() things as explicit macros, and they 
are very easily implemented through fpclassify:

#define FP_INFINITE 1
#define FP_NAN 2
#define FP_NORMAL (-1)
#define FP_SUBNORMAL (-2)
#define FP_ZERO 0
#define isfinite(_X) (fpclassify(_X) <= 0)
#define isinf(_X) (fpclassify(_X) == FP_INFINITE)
#define isnan(_X) (fpclassify(_X) == FP_NAN)
#define isnormal(_X) (fpclassify(_X) == FP_NORMAL)

fpclassify and signbit are also macros, but they are implemented using 
ordinary functionality.

If there is an explicit function behind, say, isnan or isinf, it is 
probably overridden by a macro:

#define isnan(_X) _Isnan(_X)

The ctype is() things are functions, but can be overriden with macros 
for speed (and usually are).

I don't have the C++98 standard here (still have to buy that book!), but 
the math is() functions/macros could be one area where the two languages 
diverge.

Hopefully this helps, Gregory Pietsch

--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Problem reports:       http://cygwin.com/problems.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/



More information about the Cygwin mailing list