[typeof] gcc and typeof in function return types

Hi Arkadiy and Peder et all I have been testing out replacing my return type deduction scheme in signatures with typeof. see code and errors at the end. Unfortunately gcc has major problems with it. compiles fine in VC7.1 Nevertheless I think its an important use case. Looking through the Typeof tests it doesnt seem to be there. I shall of course submit a bug report to gnu about it though maybe I'll wait to the next release assuming it includes Typeof. I dont suppose theres anything you can do about it, but I thought I'd let you know anyway. regards Andy Little #include <boost/typeof/typeof.hpp> #include <iostream> #include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP() namespace my{ template <typename T> class udt; } BOOST_TYPEOF_REGISTER_TEMPLATE(my::udt,1); namespace my{ template <typename T> class udt{ T m_value; public: T get_value()const{ return m_value;} udt():m_value(0){} explicit udt(T const & in) : m_value(in){} template <typename T1> udt<BOOST_TYPEOF_TPL(T(1) + T1(1))> operator +( udt<T1> const & in)const { typedef udt<BOOST_TYPEOF_TPL(T(1) + T1(1))> result_type; result_type result(m_value + in.get_value()); return result; } }; template <typename T> std::ostream & operator <<(std::ostream& os, udt<T> const & u) { os << "{" << u.get_value() << "}"; return os; } } int main() { my::udt<int> v1(1); my::udt<double> v2(2.4); std::cout << v1 + v2 << '\n'; } gcc 4.0.1 error: test.cpp: In member function 'my::udt<__typeof__ (boost::type_of::ensure_obj(((T)(1) + (T1)(1))))> my::udt<T>::operator+(const my::udt<T1>&) const [with T1 = double, T = int]': test.cpp:26: internal compiler error: in write_type, at cp/mangle.c:1646 Please submit a full bug report, with preprocessed source if appropriate. See <URL:http://gcc.gnu.org/bugs.html> for instructions. gcc 3.2 error test.cpp: In instantiation of `my::udt<int>': test.cpp:40: instantiated from here test.cpp:23: invalid use of template type parameter test.cpp:23: confused by earlier errors, bailing out

It's only worse with gcc-4.1 (4.1.0 20060131 (Red Hat 4.1.0-0.20)): Test2.cc:44: internal compiler error: in write_type, at cp/mangle.c:1651 (bug report filed)

Hi Andy, "Andy Little" <andy@servocomm.freeserve.co.uk> wrote
I have been testing out replacing my return type deduction scheme in signatures with typeof. see code and errors at the end.
I've seen this kind of problem before. It exists in gcc in both native and compliant mode, and can be workarounded by factoring out typeof invocation into a separate template, something like this: template<class T, class T1> struct wknd { typedef BOOST_TYPEOF_TPL(T(1) + T1(1)) type; }; template <typename T> class udt{ T m_value; public: T get_value()const{ return m_value;} udt():m_value(0){} explicit udt(T const & in) : m_value(in){} template <typename T1> udt<typename wknd<T, T1>::type> operator +( udt<T1> const & in)const { typedef udt<typename wknd<T, T1>::type> result_type; result_type result(m_value + in.get_value()); return result; } }; With this fix it seems to be compiling OK in both compliant and native mode (mingw 3.4.2) Regards, Arkadiy

"Arkadiy Vertleyb" <vertleyb@hotmail.com> wrote in message news:ds90da$fgt$1@sea.gmane.org...
Hi Andy,
"Andy Little" <andy@servocomm.freeserve.co.uk> wrote
I have been testing out replacing my return type deduction scheme in signatures with typeof. see code and errors at the end.
I've seen this kind of problem before. It exists in gcc in both native and compliant mode, and can be workarounded by factoring out typeof invocation into a separate template, something like this:
[...] OK . The workaround is sort of what I had already as the return type deduction scheme. BTW a general question. Should the non-workaround be being tested? I'm not sure what test policy should be on something you know is going to fail. Do you add this to tests bundled with the library?. Or do you just put in the workaround IOW effectively not testing this? For example if a user finds a test failing then they will assume the library is unusable right? OTOH the test is provided documenting the workaround. Is there a policy on this? regards Andy Little

Andy Little wrote: [...]
gcc 4.0.1 error:
test.cpp: In member function 'my::udt<__typeof__ (boost::type_of::ensure_obj(((T)(1) + (T1)(1))))> my::udt<T>::operator+(const my::udt<T1>&) const [with T1 = double, T = int]': test.cpp:26: internal compiler error: in write_type, at cp/mangle.c:1646 Please submit a full bug report, with preprocessed source if appropriate. See <URL:http://gcc.gnu.org/bugs.html> for instructions.
I reported this and got this response (FYI): ------- Additional Comments From jakub@redhat.com 2006-02-07 11:15 EST ------- This is a well known very old problem. Simply avoid using typeof in template arguments.

On 2/7/06, Neal Becker <ndbecker2@gmail.com> wrote:
Andy Little wrote:
[...]
gcc 4.0.1 error:
test.cpp: In member function 'my::udt<__typeof__ (boost::type_of::ensure_obj(((T)(1) + (T1)(1))))> my::udt<T>::operator+(const my::udt<T1>&) const [with T1 = double, T = int]': test.cpp:26: internal compiler error: in write_type, at cp/mangle.c:1646 Please submit a full bug report, with preprocessed source if appropriate. See <URL:http://gcc.gnu.org/bugs.html> for instructions.
I reported this and got this response (FYI): ------- Additional Comments From jakub@redhat.com 2006-02-07 11:15 EST ------- This is a well known very old problem. Simply avoid using typeof in template arguments.
This is not always simple, though. The implementation of LVALUE_TYPEOF relies on using a typeof statement as a template argument, making it very hard to implement a generalized lvalue-preserving typeof for GCC: #define BOOST_LVALUE_TYPEOF(expr)\ boost::type_of::decorate_type< \ BOOST_TYPEOF(expr), \ sizeof(*boost::type_of::classify_expression(expr)) \ >::type It also prevents us from removing the template version of BOOST_TYPEOF: BOOST_TYPEOF_TPL, which adds 'typename' where needed. This is because we cannot add typename before __typeof__(expr): Emulation: <Code> #define BOOST_TYPEOF(expr) \ boost::type_of::decode_begin<BOOST_TYPEOF_ENCODED_VECTOR(Expr) >::type #define BOOST_TYPEOF_TPL(expr) typename BOOST_TYPEOF(expr) </Code> GCC: <Code> #define BOOST_TYPEOF(expr) __typeof__(expr) #define BOOST_TYPEOF_TPL(expr) BOOST_TYPEOF(expr) </Code> so: The suggested workaround for GCC (that would allow us to remove BOOST_TYPEOF_TPL) #define BOOST_TYPEOF(expr) boost::type_of::identity<__typeof__(expr)>::type also fails because of this problem :( Regards Peder
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
participants (4)
-
Andy Little
-
Arkadiy Vertleyb
-
Neal Becker
-
Peder Holt