In addition to DevCom-923187, this was previously reported as Microsoft-internal VSO-521345, VSO-153341, VSO-194989, VSO-294538, and VSO-531712.
We resolved those bugs, saying that when LWG-1327 was resolved, the intent was to support floating-point types only. There's a comment in <cmath> about this:
https://github.com/microsoft/STL/blob/fffbd8fe05cd1a21adf2284eb6acef69e982b3c7/stl/inc/cmath#L674
However, this issue keeps being encountered by users, and I do not see clear language in the current WP justifying our implementation. WG21-N4849 [cmath.syn]/2 simply says "For each set of overloaded functions within <cmath>, with the exception of abs, there shall be additional overloads sufficient to ensure:" and signbit() etc. is a set of overloaded functions within <cmath>.
I believe that either this is a bug in our implementation, or it's a defect in the Standard that needs an LWG issue to be filed (specifically mentioning the "classification/comparison functions" alongside abs).
I've asked on the LEWG mailing list a few times about this (choosing to resolve in favor of providing the overloads or not is an LEWG rather than LWG question) but haven't gotten any response. I wanted to write a paper about it but wanted to wait until the "mandating the standard library" papers got merged.
It looks like WG21-P0175 may have broken the reasoning we use for LWG-1327 -- the old wording said that the "sufficient additional overloads only apply to functions from the C standard library" and in the C standard library they are macros. Now we explicitly declare them as functions...
LWG-1327 is resolved by Motion 27 at Rapperswil 2010. That applied the wording for US136 from WG21-N3102. The description preceding the wording says
Each macro is better described in C++ as three overloads, with operand(s) of type float,
double, and long double. Moreover, as with the math functions described in this same section, each of the functions has "sufficient additional overloads" to simulate the effect of the C type-generic functions.
This was also presented to WG14 at the same time; WG14-N1459 makes clear that the C comparison macros are intended to support heterogeneous floating-point types. That's only realizable in the C++ wording if "sufficient additional overloads" apply.
We should actually tag this as LEWG issue needed because this is a library design issue.
Closed #908 as a duplicate of this bug; it received 6 thumbs-up in addition to the submitter.
One thing I forgot to note there: unlike the rest of the fpclassify family, signbit can do something meaningful for integers so we might want to consider it separately (as opposed to isnan/isfinite et al. which are almost certainly mistakes to call on integers).
From: Stephan T. Lavavej notifications@github.com
Sent: Saturday, June 20, 2020 07:06 PM
To: microsoft/STL STL@noreply.github.com
Cc: Billy O'Neal (VC LIBS) bion@microsoft.com; Comment comment@noreply.github.com
Subject: Re: [microsoft/STL]
Closed #908https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fmicrosoft%2FSTL%2Fissues%2F908&data=02%7C01%7Cbion%40microsoft.com%7C816c466ffca34e5be26c08d81587c8b7%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637283020214117113&sdata=p9URfQhgYB1JcKgq0EHFI%2F9CSAPTnwpGV8ux2OPrLdk%3D&reserved=0 as a duplicate of this bug; it received 6 thumbs-up in addition to the submitter.
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHubhttps://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fmicrosoft%2FSTL%2Fissues%2F519%23issuecomment-647068256&data=02%7C01%7Cbion%40microsoft.com%7C816c466ffca34e5be26c08d81587c8b7%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637283020214127108&sdata=8RA%2FZhqt3D7NUn9pbqTw9nhaf7%2FDht%2BeRcqgDmfpiOY%3D&reserved=0, or unsubscribehttps://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fnotifications%2Funsubscribe-auth%2FAALZF37AAKZF3RLHV2UGNWTRXVTMHANCNFSM4KYVS6RA&data=02%7C01%7Cbion%40microsoft.com%7C816c466ffca34e5be26c08d81587c8b7%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637283020214127108&sdata=bu6oA6IyEc0ioyCh%2BWsSqUYEE58zGlQptYse9ebELrw%3D&reserved=0.
@BillyONeal The usefulness of std::is_integral overloads for std::isnan etc. (which I assume will just return false as-if return isnan(static_cast<double>(x)) had been called) is, as I see it, that they can be used to simplify writing templates. So, those overloads do something meaningful in that respect. :-)
@BillyONeal The usefulness of
std::is_integraloverloads forstd::isnanetc. (which I assume will justreturn falseas-ifreturn isnan(static_cast<double>(x))had been called) is, as I see it, that they can be used to simplify writing templates. So, those overloads do something meaningful in that respect. :-)
That is actually want scares me: it encourages code that looks correct but falls over if the user passes more than 53 bits; I would kinda like to see the user explicitly if constexpr in those places to indicate that they have considered both archetypical arithmetic types.
_but falls over if the user passes more than 53 bits_
Are you thinking about the functions that'll return a double? If so, yes, I think it's was a bad idea to add _integral type_ overloads for those. For the functions returning bool (not only signbit) I think the overloads have real value.
_I would kinda like to see the user explicitly
if constexprin those places to indicate that they have considered both archetypical arithmetic types._
isnan(value) in an instantiation of a template where value is an integral type will (most probably, or even _should_) be optimized to (false) and then that branch will be discarded - but if we're talking about functions returning double I totally agree.
Are you thinking about the functions that'll return a double?
I mean all code that might accidentally mix these things. If the user called something in the fpclassify family that suggests that they are expecting the inputs to behave like floats. Consider the straw man:
template<class T>
T f(T x) {
T y = x + 42.0;
if (isfinite(y)) { y = -y; }
return y;
}
works great until T is long long and the input doesn't fit in 53 bits. Maybe stopping that with this isn't a huge win, but I think the amount of code that becomes truly generic across floats and integrals but for these functions is small. But I also am probably not the target user here; that's why I wanted the committee to provide clarification here.
that's why I wanted the committee to provide clarification here
Great! Have you or somebody else written a proposal? I'd like to see where this goes ....
Examples where the loss of precision when converted to double does change the result:
const long long x = 0x0fff'ffff'ffff'ffffLL;
assert(ilogb(x) == 59); // fails
assert(llround(x) == x); // fails
Most helpful comment
In addition to DevCom-923187, this was previously reported as Microsoft-internal VSO-521345, VSO-153341, VSO-194989, VSO-294538, and VSO-531712.
We resolved those bugs, saying that when LWG-1327 was resolved, the intent was to support floating-point types only. There's a comment in
<cmath>about this:https://github.com/microsoft/STL/blob/fffbd8fe05cd1a21adf2284eb6acef69e982b3c7/stl/inc/cmath#L674
However, this issue keeps being encountered by users, and I do not see clear language in the current WP justifying our implementation. WG21-N4849 [cmath.syn]/2 simply says "For each set of overloaded functions within
<cmath>, with the exception ofabs, there shall be additional overloads sufficient to ensure:" andsignbit()etc. is a set of overloaded functions within<cmath>.I believe that either this is a bug in our implementation, or it's a defect in the Standard that needs an LWG issue to be filed (specifically mentioning the "classification/comparison functions" alongside
abs).