perl5
perl5 copied to clipboard
POSIX::is*** floating-point testing functions should not return NV
C99 floating-point comparison (isgreater
, isunordered
, ...), classification (isinf
, isfinite
, ...) and signbit
macros are semantically boolean functions returning int
, but their corresponding XSUBs in POSIX.xs used to return NV.
This PR will change them to return integers, and actually return immortal "1" when underlying C macro/functions returned nonzero value, because these nonzero value might be C library/compiler dependent.
Now that we have stable boolean values, should these functions not return those?
Now that we have stable boolean values, should these functions not return those?
Oh, actually looking at the code I see they do for true, but not for false. I'm not sure I agree with the backwards-compatibility argument enough to justify the mixed-type return.
Oh, actually looking at the code I see they do for true, but not for false.
I have once tried to make them return &PL_sv_no
for false, but this broke existing tests like is(signbit(2), 0, ...)
(found in ext/POSIX/t/math.t
).
Because these functions used to return numeric value for long times, I think that there might already exist perl programs which expect these functions to return "0"
for false, not a zero-length string.
I have once tried to make them return
&PL_sv_no
for false, but this broke existing tests likeis(signbit(2), 0, ...)
(found inext/POSIX/t/math.t
).Because these functions used to return numeric value for long times, I think that there might already exist perl programs which expect these functions to return
"0"
for false, not a zero-length string.
On further thought, unlike is*
, signbit
is not a predicate, it returns the value of the sign bit, so that should be returning zero or one as an IV, not a boolean (even in the 1
case).
On further thought, unlike
is*
,signbit
is not a predicate, it returns the value of the sign bit, so that should be returning zero or one as an IV, not a boolean (even in the1
case).
C99 (and POSIX) seem to say that the signbit
macro returns some nonzero value if its argument is negative, not the value of the sign bit.
(For example, on x86 with x87 FPU, GCC's signbit
might return 512.)
So I think it should be treated as a predicate like other is*
macros, despite its name.
@ilmari is it ok to merge this with you
I remain of the opinion that is*
should return booleans always, and signbit
should return a plain IV.
@t-a-k Please respond
I still think that signbit
should be treated as a boolean function, because:
-
POSIX says
The signbit() macro shall return a non-zero value if and only if the sign of its argument value is negative.
(C99 seems to describe
signbit
similarly.) This is the same wording with otheris***
semantically-boolean function/macros such asisfinite
. "Non-zero" value is not specified, so a (portable) program has no other way than to treat its return value as a boolean by examining whether the value is zero or non-zero. -
C and POSIX seems not to define "sign bit" for floating types in any way (they do not assume any binary format for floating types; neither the exact meaning of sign bit nor even its existence is assumed). So, despite its name, I think it unreasonable to interpret
signbit
as returning "the value of the sign bit". -
In C++, its counterpart (
signbit
overloaded function) is defined to returnbool
.