X-Spam-Check-By: sourceware.org Message-ID: <440357EA.3060209@comcast.net> Date: Mon, 27 Feb 2006 14:50:02 -0500 From: Gregory Pietsch User-Agent: Mozilla/5.0 (Windows; U; Win 9x 4.90; en-US; rv:1.8.0.1) Gecko/20060130 SeaMonkey/1.0 MIME-Version: 1.0 To: Dave Korn CC: newlib AT sourceware DOT org, cygwin AT cygwin DOT com, newlib AT sources DOT redhat DOT com Subject: Re: gcc-3.4.4-1: c++: cmath: calling std::isnan results in endless loop References: <01d101c63bb9$ef9ead20$a501a8c0 AT CAM DOT ARTIMI DOT COM> In-Reply-To: <01d101c63bb9$ef9ead20$a501a8c0@CAM.ARTIMI.COM> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-owner AT cygwin DOT com Mail-Followup-To: cygwin AT cygwin DOT com Delivered-To: mailing list cygwin AT cygwin DOT com 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) as a tail call to >> __gnu_cxx::__capture_isnan(double), and it compiles >> __gnu_cxx::__capture_isnan(double) to >> __gnu_cxx::isnan(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 -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/