
On Wed, Sep 22, 2004 at 02:20:01PM +0200, Guillaume Melquiond wrote:
Le mer 22/09/2004 ? 12:19, Jonathan Wakely a ?crit :
On Wed, Sep 22, 2004 at 11:27:09AM +0200, Guillaume Melquiond wrote:
right. Version of GCC is being used in numeric/interval/detail/bugs.hpp to discover capabilities of runtime, thus problem.
Not to discover capabilities, it is to discover namespaces. At the time of GCC 3.4, the developers decided that the inverse hyperbolic functions should not be in the std namespace anymore (they were before). It is the reason why the GCC version is tested. [snip] However, another test in boost/numeric/interval/detail/bugs.hpp seems wrong to me:
# if defined(__GNUC__) && (__GNUC__ == 3) && (__GNUC_MINOR__ > 3) # define BOOST_NUMERIC_INTERVAL_using_ahyp(a) using ::a # elif defined(BOOST_HAS_INV_HYPERBOLIC) # define BOOST_NUMERIC_INTERVAL_using_ahyp(a) using std::a # endif
This implies that GCC 3.3 (and earlier) puts the inverse hyperbolic functions in namespace std. According to a simple test (*) I've just run, none of GCC 3.0.4 on linux, 3.3.3 on FreeBSD or 3.4.3 on FreeBSD declares acosh in namespace std.
FreeBSD is not necessarily a good example since there has been a few problems with respect to supporting C99 mathematical functions. But I verified with Linux, and you are right: the C99 functions did leave the std namespace a lot sooner than what I thought.
Agreed, but it's the only system I have available right now to test GCC 3.3 and higher. Since FreeBSD doesn't use glibc the functions come from a different source - but the namespace they end up in is decided by libstdc++ and AFAIK is consistent across FreeBSD and Linux.
Only GCC 2.x seems to declare those functions in namespace std, but that's probably because namespace std == global namespace in GCC 2.x (all std:: qualifiers are effectively ignored)
Should the first line of the test above be changed as follows?
# if defined(__GNUC__) && (__GNUC__ == 3)
According to your information, even the version number could be ignored since GCC 2.x assumes the root and the std namespaces are equivalent.
Possibly, yes - although I can't remember the details of how GCC 2.x ignores std:: qualifiers. But the above test won't catch MinGW, where all this trouble started. Doh. The attached patch might be better. It ignores libstdc++ when deciding whether to set BOOST_HAS_INV_HYPERBOLIC (since that depends on the C runtime, not C++). Since MinGW doesn't use GlibC that macro should not be set. Then later when finding the namespaces (which does depend on C++ library) we check whether BOOST_HAS_INV_HYPERBOLIC before deciding on the namespace to use. Because BOOST_HAS_INV_HYPERBOLIC is not set for MinGW it won't define a using decl at all. This might break FreeBSD, which does have those functions but doesn't get them from glibc, so the __GLIBC__ check won't be true, and BOOST_HAS_INV_HYPERBOLIC won't get set. We should do an additional check for a recent-enough FreeBSD libc, and set BOOST_HAS_INV_HYPERBOLIC if found.
Why is BOOST_HAS_INV_HYPERBOLIC defined if you're using Glibc but not libstdc++? libstdc++ doesn't make the functions unavailable, it just doesn't put them in namespace std.
I don't know; it's also something I was wondering. But since the library works and is used on a lot more platform than what I have access to, I refrained from experimenting.
Understandable - I don't have access to MinGW (or linux during the day) so can't verify my "fixes" work.
However, in the meantime, let's see what we can do to improve the current situation. I would modify the BOOST_HAS_INV_HYPERBOLIC macro so that it really means these C99 functions are defined.
Yes, agreed. That's what the attached patch tries to do.
In case they are not, dummy functions would be defined in a detail namespace so that the compilers don't complain about unknown identifier, and ADL could still be used (this is mandatory). And in all cases, the BOOST_NUMERIC_INTERVAL_using_ahyp macro would point to the correct namespace (root, std, or the dummy detail one). How does it sound?
Much better. This way the two properties (if the functions are available, and if so which namespace they are in) are tested for separately. If BOOST_HAS_INV_HYPERBOLIC means the functions are available we can fix it later to account for FreeSBD and other cases where the functions are provided by something other than Glibc. Another possiblity would be to make use of the _GLIBCXX_USE_C99 (formerly _GLIBCPP_USE_C99) macro that libstdc++ defines to say whether the C runtime is C89 or C99 (I think this is false for MinGW?) but that would exclude FreeBSD, which has the inverse hyperbolic functions, but not a complete C99 runtime, so libstdc++ doesn't set _GLIBCXX_USE_C99. It would also only work for libstdc++, and we've said it is better to set BOOST_HAS_INV_HYPERBOLIC independently of the stdlib. jon -- [Inlines] are the third most-misused C++ feature (after inheritance and overloading). - Nathan Myers