Boost logo

Boost Users :

Subject: [Boost-users] [proto]Compile issue on Sun Solaris 10, Sun Studio 12.2
From: Sascha Ochsenknecht (s.ochsenknecht_at_[hidden])
Date: 2010-10-05 12:13:43


Hello,

I got an error from the Sun Studio 12.2 (CC 5.11) when trying to compile
my sources.
The error comes out of the Boost.Proto library (actually I'm doing
something with Boost.Spirit and Boost.Spirit is using Boost.Proto ...,
but I don't think that the problem is in the client code, it seems to
come from the buggy compiler). I'm using Boost 1.43.

This is what I got from the compiler:

"...include/boost/proto/detail/decltype.hpp", line 343: Error: Partial
specialization parameter V is not used in the arguments.
"...include/boost/proto/transform/arg.hpp", line 287: Error: Partial
specialization for boost::proto::_byval::result has identical arguments.
"...include/boost/proto/extends.hpp", line 600: Error: type is not a
member of boost::result_of<boost::proto::domainns_::default_domain>.
"...include/boost/spirit/home/support/terminal.hpp", line 237: Where:
While specializing
"boost::proto::exprns_::extends<boost::proto::exprns_::expr<boost::proto::tag::terminal,
boost::proto::argsns_::term<boost::spirit::tag::bin>, 0>,
boost::spirit::terminal<boost::spirit::tag::bin>,
boost::proto::domainns_::default_domain, 0>".

(the following is talking about
"include/boost/proto/detail/decltype.hpp", line 343)

With g++ this code compiles without any problems and runs as expected.
Searching around the internet, I got the following bug entry of the Sun
Studio compiler: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6926895

It looks like a similar problem. The bug entry contains a small example
which reproduces the compile error:

template <typename T> struct test { T t; };
template <typename T, typename X> struct test<X T::*> { X T::* x; };
template <typename T> struct test2 {};
template <typename T, typename X> struct test2< test<X T::*> > { test<X
T::*> xt; };

int main() {
  test<int> a;
  a.t = 1;
  int test<int>::* s = &test<int>::t;
  test<int test<int>::*> a2;
  a2.x = s;
  test2<test<int test<int>::* > > a3;
  a3.xt = a2;
  return a.*a3.xt.x;
}

$ CC example.C
"example.C", line 4: Error: Partial specialization parameter T is not
used in the arguments.

The bug entry also provides a workaround which seems to work. Replace
the template types with the following:

template <typename T> struct helper { };
template <typename T> struct test2 : public test2< helper<T> > { };
template <typename T> struct test2<helper< T> > { } ;
template <typename T, typename X > struct test2< helper<test<X T::* > >
 {test<X T::*> xt; };

I would like to try a similar workaround adapted to the Boost.Proto
source code. I tried several things but since I'm not fully aware what
is going on in the proto sources and what is the exact reason the
compiler fails, I couldn't make it work so far.

Does anybody had a similar problem or does anybody know how to adapt the
Boost.Proto source to make the Sun compiler happy?

BTW: For me it would be ok for now to patch my local Boost source files.

Here is the snippet from proto/detail/decltype.hpp:

////////////////////////////////////////////////////////////////////////////////////////////
// result_of_ is a wrapper around boost::result_of that also handles
"invocations" of
// member object pointers.
template<typename T, typename Void = void>
struct result_of_
  : boost::result_of<T>
{};

   // THE FOLLOWING IS TROUBLE MAKER FOR THE SUN COMPILER ->
template<typename T, typename U, typename V>
struct result_of_<T U::*(V), typename
enable_if_c<is_member_object_pointer<T U::*>::value>::type>
{
    BOOST_STATIC_CONSTANT(bool, is_V_a_smart_ptr = 2 ==
sizeof(test_V_is_a_U<U>(&lvalue(make<V>()))));
    BOOST_STATIC_CONSTANT(bool, is_ptr_to_const = 2 ==
sizeof(test_ptr_to_const(BOOST_PROTO_GET_POINTER(U, make<V>()))));

    // If V is not a U, then it is a (smart) pointer and we can always
return an lvalue.
    // Otherwise, we can only return an lvalue if we are given one.
    typedef
        typename mpl::eval_if_c<
            (is_V_a_smart_ptr || is_reference<V>::value)
          , mpl::eval_if_c<
                is_ptr_to_const
              , add_reference<typename add_const<T>::type>
              , add_reference<T>
>
          , mpl::identity<T>
>::type
    type;
};

Thanks in advance,
Sascha


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net