
On Wed, Aug 8, 2012 at 8:59 PM, John Bytheway <jbytheway+boost@gmail.com> wrote:
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
For curiosity, when using Boost.Parameter what error did you see? (Even if I understand the error was ultimately not there.)
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?
Thanks, --Lorenzo