This is the mail archive of the cygwin mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


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/


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]