[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