X-Spam-Check-By: sourceware.org Message-ID: Date: Thu, 30 Nov 2006 14:58:32 -0500 From: "Lev Bishop" To: cygwin AT cygwin DOT com Subject: Re: isnan() causes segfault In-Reply-To: MIME-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Content-Disposition: inline References: Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: 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 On 11/30/06, Lev Bishop wrote: > On 11/30/06, Lev Bishop wrote: > > On 11/30/06, Eric Lilja wrote: > > > If compiled with: > > > $ g++ -Wall -Wextra -std=c++98 -pedantic -g isnantest.cpp -o run > > > (those are the flags we have been using in this course). > > > But it doesn't stackdump if compiled simply with: > > > $ make isnantest > > > g++ isnantest.cpp -o isnantest > > > > I was able to reproduce this behaviour. > > > > There seems to be a difference in the generated assembler. > > The -std=c++98 seems to be the only switch that matters. > > Here is a diff. File isnantest2.s is the stackdumping one (ie the one > > with -std=c++98) > > > > And the cause of the failure seems to be mutual recursion in > /usr/lib/gcc/i686-pc-cygwin/3.4.4/include/c++/cmath > > where at line 458: > template > int > __capture_isnan(_Tp __f) { return isnan(__f); } > > which calls at line 532: > template > int > isnan(_Tp __f) { return __capture_isnan(__f); } > > which calls back to __capture_isnan(). So, the deal is that /usr/include/math.h has a macro definition for isnan(). This is at line 138, starting with a perhaps relevant comment: /* Note: isinf and isnan were once functions in newlib that took double * arguments. C99 specifies that these names are reserved for macros * supporting multiple floating point types. Thus, they are * now defined as macros. Implementations of the old functions * taking double arguments still exist for compatibility purposes. */ #define isinf(x) \ (__extension__ ({__typeof__(x) __x = (x); \ (sizeof (__x) == sizeof (float)) ? __isinff(__x) : __isinfd(__x);})) #define isnan(x) \ (__extension__ ({__typeof__(x) __x = (x); \ (sizeof (__x) == sizeof (float)) ? __isnanf(__x) : __isnand(__x);})) So, because /usr/lib/gcc/i686-pc-cygwin/3.4.4/include/c++/cmath captures this definition in it's __capture_isnan() normally things work. However, -std=c++98 causes __STRICT_ANSI__ to be defined, and /usr/include/math.h protects the macro definitions within a #ifndef __STRICT_ANSI__ , things break in this situation. It would appear that fpclassify(), isfinite(), isinf(), isgreater(), and others will also be affected. I'm not really clear about the implications of this, nor what the relevant standards have to say, but perhaps the correct thing is to change the guard at line 105 of /usr/include/math.h to #if !defined(__STRICT_ANSI__) || defined (__cplusplus) as is done in the same file for atanf(), cosf(), et al. Something for the newlib folks to deal with, I suppose. Lev -- 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/