Boost logo

Boost :

Subject: Re: [boost] [type_traits][parameter] Inconsistent boost::is_convertible between gcc and clang
From: Jeffrey Lee Hellrung, Jr. (jeffrey.hellrung_at_[hidden])
Date: 2012-08-10 23:57:25


On Wed, Aug 8, 2012 at 8:59 PM, John Bytheway <jbytheway+boost_at_[hidden]>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
> 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).
>

I would consider clang correct and gcc incorrect (this is without
consulting the documentation).

> 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.
>

That appears to explain it; again, I would consider the add_reference
incorrect and a limitation. If one wants to add a reference qualifier (when
using what I consider a correct implementation of is_convertible), one may
do so explicitly; but, in the case of gcc's implementation, one can't
prevent the addition of reference qualifiers, so there's no way to test
convertibility from rvalues.

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,

Well, *technically*, such other code would be depending on an
*implementation*, let's say, "feature", that is, according to your reading,
undocumented.

so perhaps it would
> be safer to tweak the clang implementation instead, and deviate from
> std::is_convertible.
>

Other code aside, I believe the correct thing to do would be to put the gcc
implementation more in line with the clang, std, and Boost-documented
behavior. Maybe make the change to the gcc implementation and see what
fails within Boost first?

Any thoughts?
>

I guess so :)

- Jeff


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk