libm lacks C99 functions -> no c++11 cmath in libstdc++
    Dmitry Marakasov 
    amdmi3 at amdmi3.ru
       
    Wed Jan 29 16:41:40 UTC 2014
    
    
  
Hi!
Gerald haven't responded yet, so I though I'd better post in on the
list as well for wider discussion.
In short:
- our libm lacks some C99 functions: erfl erfcl lgammal tgammal
- bad enough by itself, it affects libstdc++ from ports' gcc in such a
  way that it disables C++11 math completely (along with a lot more
  other more widely used math functions)
- we may probably implement these by calling less-precise
  erf erfc lgamma tgamma as we do with other functions as we alredy
  do with some others
----- Forwarded message from Dmitry Marakasov <amdmi3 at hades.panopticon> -----
Date: Tue, 21 Jan 2014 19:13:07 +0400
From: Dmitry Marakasov <amdmi3 at hades.panopticon>
To: gerald at FreeBSD.org
Subject: libstdc++ from ports' gcc's and cmath
Hi!
I've was just curious why one of my ports doesn't build on < 10.x and
found the following:
This code:
---
#include <cmath>
int main() { std::hypot(3.0, 4.0); }
---
won't build even with latest gcc:
---
% g++49 -std=c++11 2.cc
2.cc: In function 'int main()':
2.cc:2:14: error: 'hypot' is not a member of 'std'
 int main() { std::hypot(3.0, 4.0); }
              ^
2.cc:2:14: note: suggested alternative:
In file included from /usr/local/lib/gcc49/include/c++/cmath:44:0,
                 from 2.cc:1:
/usr/include/math.h:276:8: note:   'hypot'
 double hypot(double, double);
        ^
---
Why's std::hypot not defined?
--- /usr/local/lib/gcc49/include/c++/cmath
...
#ifdef _GLIBCXX_USE_C99_MATH_TR1
...
namespace std _GLIBCXX_VISIBILITY(default)
{
  ...
  constexpr float
  hypot(float __x, float __y)
  { return __builtin_hypotf(__x, __y); }
  constexpr long double
  hypot(long double __x, long double __y)
  { return __builtin_hypotl(__x, __y); }
  template<typename _Tp, typename _Up>
    constexpr typename __gnu_cxx::__promote_2<_Tp, _Up>::__type
    hypot(_Tp __x, _Up __y)
    {
      typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type;
      return hypot(__type(__x), __type(__y));
    }
---
As you can see, it's hidden under _GLIBCXX_USE_C99_MATH_TR1.
What if I define _GLIBCXX_USE_C99_MATH_TR1?
---
% g++49 -std=c++11 2.cc
In file included from 2.cc:1:0:
/usr/local/lib/gcc49/include/c++/cmath:1064:11: error: '::erfl' has not been declared
   using ::erfl;
           ^
/usr/local/lib/gcc49/include/c++/cmath:1068:11: error: '::erfcl' has not been declared
   using ::erfcl;
           ^
/usr/local/lib/gcc49/include/c++/cmath:1104:11: error: '::lgammal' has not been declared
   using ::lgammal;
           ^
/usr/local/lib/gcc49/include/c++/cmath:1176:11: error: '::tgammal' has not been declared
   using ::tgammal;
           ^
---
That's the very reason _GLIBCXX_USE_C99_MATH_TR1 is not defined:
libstdc++ configure checks for availability of all C99 math functions in
our math library, doesn't find these four and disable whole C99 math
set.
libstdc++ works this around by using lower-precision variants (e.g.
erf instead of erfl) and issues a warning on linking.
So I wonder: could libstdc++ be made more usable for C++11 code in some
way? That's crucial for pre-clang FreeBSD branches which will live for
quite some time, and this is useful for gcc users on post-clang world.
The simple solution would be to disable named 4 functions, but make all
others available. The better would be to do what libc++ does, with
corresponding warnings.
What do you think?
-- 
Dmitry Marakasov   .   55B5 0596 FF1E 8D84 5F56  9510 D35A 80DD F9D2 F77D
amdmi3 at amdmi3.ru  ..:  jabber: amdmi3 at jabber.ru    http://www.amdmi3.ru
----- End forwarded message -----
-- 
Dmitry Marakasov   .   55B5 0596 FF1E 8D84 5F56  9510 D35A 80DD F9D2 F77D
amdmi3 at amdmi3.ru  ..:  jabber: amdmi3 at jabber.ru    http://www.amdmi3.ru
    
    
More information about the freebsd-current
mailing list