[libcxx-commits] [PATCH] D60234: Added std::assoc_legendre and std::legendre [sf.cmath]
Andre Brand via Phabricator via libcxx-commits
libcxx-commits at lists.llvm.org
Sun May 5 14:12:18 PDT 2019
thebrandre added a comment.
I recently became aware of the fact that gcc and msvc don't aggree on "Exceptions or Error Codes?" (Section III.D in N1542 <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1542.pdf>)
N1542 <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1542.pdf> is in favor of signaling domain errors via
#include <cerrno>
errno = EDOM;
for consistency with other functions from cmath such as the log function and for compatibility with C.
VS2019's implementation does exactly that whereas gcc throws an std::domain_error. (As an aside: the exceptions of legendre got removed in gcc-9 but laguerre still throws for x<0 .)
The C++17 standard and N3060 <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3060.pdf> simply refer to it as "domain error". Unfortunately, this term is ambiguous because both EDOM and std::domain_error are known by this name.
As N1542 <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1542.pdf> suggests to use errno for perfectly valid reasons, I am inclined to change my patches accordingly even though it means that we'd diverge from libstdc++ in that matter.
Maybe/hopefully someone can help out with any (official) statements that give clearer directions?
Interestingly, boost is in-between: when you use boost::math::policies::errno_on_error instead of the default policy, you'll get close to MSVC's behavior. The default policy throws std::domain_error.
I'd also like to point out that the situation is even worse than that. For example, log(-1) not only sets errno but also raises a floating-point exception as if
std::feraiseexcept(FE_INVALID);
were called. This is also referred to as a "domain error".
We could mimic the behavior of the log function by introducing something like the following:
#include <cerrno>
#include <cmath>
#include <cfenv>
void __raise_math_domain_error() _NOEXCEPT {
#if math_errhandling & MATH_ERREXCEPT == MATH_ERREXCEPT
std::feraiseexcept(FE_INVALID);
#endif
#if math_errhandling & MATH_ERRNO == MATH_ERRNO
errno = EDOM;
#endif
}
Let's call that one "errno + floating-point exception".
However, neither boost nor msvc seem to go beyond "errno".
So when it comes down to the question "std::domain_error, errno, or 'errno + floating-point exception'?", I personally think errno is the way to go ...
but I would be sooooo happy for some feedback on that. ;-)
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D60234/new/
https://reviews.llvm.org/D60234
More information about the libcxx-commits
mailing list