Skip to content

Commit

Permalink
isnan (long double): always use the C99 version
Browse files Browse the repository at this point in the history
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
  • Loading branch information
tonycoz committed Jun 3, 2024
1 parent 0a0364b commit 4ce0fbf
Showing 1 changed file with 2 additions and 5 deletions.
7 changes: 2 additions & 5 deletions perl.h
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down

0 comments on commit 4ce0fbf

Please sign in to comment.