From 4ce0fbf1d0aae8ea79253d078840f1a65fbbd150 Mon Sep 17 00:00:00 2001 From: Tony Cook Date: Wed, 22 May 2024 14:02:53 +1000 Subject: [PATCH] isnan (long double): always use the C99 version C99 requires that isnan() is a generic macro that accepts the standard floating point types (float, double, long double). We always include math.h eventually, so this macro should be available. This is complicated by C++. C++98 depends on C89, which does not require isnan(), but since we do require C99, I think we need to require a minimum of C++11, which follows C99. C++11 does *not* define isnan() as a macro, but as a set of overloaded functions, which produces almost the same result, the difference being that the macro test that was done by this code is no longer valid. The old code would fail to build with C++ long double builds with gcc on Window: ..\sv.c: In function 'size_t S_infnan_2pv(NV, char*, size_t, char)': ..\perl.h:2680:34: error: 'isnanl' was not declared in this scope; did you mean 'isnan'? 2680 | # define Perl_isnan(x) isnanl(x) | ^~~~~~ ..\sv.c:2882:14: note: in expansion of macro 'Perl_isnan' 2882 | else if (Perl_isnan(nv)) { | ^~~~~~~~~~ ..\sv.c: In function 'U8* S_hextract(NV, int*, bool*, U8*, U8*)': ..\perl.h:2680:34: error: 'isnanl' was not declared in this scope; did you mean 'isnan'? 2680 | # define Perl_isnan(x) isnanl(x) | ^~~~~~ ..\perl.h:8605:69: note: in expansion of macro 'Perl_isnan' 8605 | # define Perl_fp_class_denorm(x) ((x) != 0.0 && !Perl_isinf(x) && !Perl_isnan(x) && PERL_ABS(x) < NV_MIN) | ^~~~~~~~~~ ..\sv.c:11604:49: note: in expansion of macro 'Perl_fp_class_denorm' 11604 | #define HEXTRACT_GET_SUBNORMAL(nv) *subnormal = Perl_fp_class_denorm(nv) | ^~~~~~~~~~~~~~~~~~~~ ..\sv.c:11672:9: note: in expansion of macro 'HEXTRACT_GET_SUBNORMAL' 11672 | HEXTRACT_GET_SUBNORMAL(nv); | ^~~~~~~~~~~~~~~~~~~~~~ and with gcc 14.2, which requires prototypes per C99: In file included from ..\sv.c:32: ..\sv.c: In function 'S_infnan_2pv': ..\perl.h:2680:34: error: implicit declaration of function 'isnanl'; did you mean 'isnan'? [-Wimplicit-function-declaration] 2680 | # define Perl_isnan(x) isnanl(x) | ^~~~~~ ..\sv.c:2882:14: note: in expansion of macro 'Perl_isnan' 2882 | else if (Perl_isnan(nv)) { | ^~~~~~~~~~ gmake: *** [GNUmakefile:1430: mini\sv.o] Error 1 --- perl.h | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/perl.h b/perl.h index 9788654975ff..1d12d9f27765 100644 --- a/perl.h +++ b/perl.h @@ -2676,11 +2676,8 @@ extern long double Perl_my_frexpl(long double x, int *e); # endif # endif # ifndef Perl_isnan -# if defined(HAS_ISNANL) && !(defined(isnan) && defined(HAS_C99)) -# define Perl_isnan(x) isnanl(x) -# elif defined(__sgi) && defined(__c99) /* XXX Configure test needed */ -# define Perl_isnan(x) isnan(x) -# endif + /* C99 requites that isnan() also support long double */ +# define Perl_isnan(x) isnan(x) # endif # ifndef Perl_isinf # if defined(HAS_ISINFL) && !(defined(isinf) && defined(HAS_C99))