|
Boost : |
Subject: [boost] [type_traits][parameter] Inconsistent boost::is_convertible between gcc and clang
From: John Bytheway (jbytheway+boost_at_[hidden])
Date: 2012-08-08 23:59:47
I have been tracking down an issue with some of my code which compiles
fine with gcc but not clang. It manifested as a failure in
Boost.Parameter but I eventually pinned it down to an inconsistency in
the behaviour of boost::is_convertible. The following program
demonstrates the issue:
==============
#include <boost/type_traits/is_convertible.hpp>
#include <boost/static_assert.hpp>
class A {};
int main()
{
BOOST_STATIC_ASSERT((boost::is_convertible<A, A&>::value));
}
==============
This compiles fine under g++ (4.7.1), but the assertion fires under
clang++ (r160940).
This is not too surprising because is_convertible is implemented in
completely different ways on the two compilers:
- on clang it is in terms of the __is_convertible intrinsic, which
behaves like std::is_convertible and fails because rvalue references
don't convert to lvalue references.
- on gcc it has a complex custom implementation which at some point
performs add_reference<> on the first argument and thus determines that
the conversion is OK.
Reading the docs for boost::is_convertible I think the clang
interpretation is closer to the intention, in which case the gcc
implementation is wrong, and so is Boost.Parameter (which relies on this
behaviour).
On the other hand, I suspect there's probably other code out there that
depends on this in a similar way to Boost.Parameter, so perhaps it would
be safer to tweak the clang implementation instead, and deviate from
std::is_convertible.
Any thoughts?
John Bytheway
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk