From: Jonathan Wakely (cow_at_[hidden])
Date: 2004-09-22 08:14:22
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.
> > 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.
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
> > 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?
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.
-- [Inlines] are the third most-misused C++ feature (after inheritance and overloading). - Nathan Myers