
Robert Ramey wrote:
Rene Rivera wrote:
David Abrahams wrote:
Rene Rivera <grafik.list@redshift-software.com> writes:
Of course :-) What I did was this:
template<class Derived, class Base> BOOST_DLLEXPORT const void * void_cast_register( const Derived * /* dnull = NULL */, const Base * /* bnull = NULL */ ){ boost::python::detail::force_instantiate( void_cast_detail::void_caster_primitive< const Derived, const Base >::instance); return & void_cast_detail::void_caster_primitive< const Derived, const Base
::instance; }
Ouch! Looks like a nasty bug. If you can generate a small test case I can pass it directly to their compiler engineer.
I'll try.
This has been very interesting. Now I'm wondering why test_void_cast passes. It seems to be a simple test case to me and should fail according to the above. But it passes on all the CW compilers.
I'm starting to suspect that it has something to do with the template depth and complexity. In test_void_cast the void_cast_register gets called directly, so it doesn't have problems. But at some point in calling it indirectly it likely gets confused. Don't really know.. As I've been unable to duplicate the problem. Here's my current, now fairly complicated as I keep adding to it, test.. -- -- Grafik - Don't Assume Anything -- Redshift Software, Inc. - http://redshift-software.com -- rrivera/acm.org - grafik/redshift-software.com -- 102708583/icq - grafikrobot/aim - Grafik/jabber.org #include <iostream> #include <boost/mpl/eval_if.hpp> #include <boost/mpl/identity.hpp> #include <boost/type_traits/is_pod.hpp> struct Z { Z() {} virtual ~Z() {} }; struct X { const Z & m; X(const Z & n); virtual ~X(); static void reg(const X *); }; template <typename T> struct A : public X { static const A a; A(); }; template <typename T> A<T>::A() : X(*(new Z())) { std::cout << __PRETTY_FUNCTION__ << '\n'; this->reg(& a); } template <typename T> const A<T> A<T>::a; template <typename T> const void * instantiate(const T * t) { return &A<T>::a; } template <typename T> struct Q { struct nothing { static void invoke() { } }; template <typename S> struct something { static void invoke() { instantiate<S>(static_cast<const S *>(0)); } }; static void invoke() { typedef typename boost::mpl::eval_if< typename boost::is_pod<T>, boost::mpl::identity< something<T> >, boost::mpl::identity< nothing > >::type typex; typex::invoke(); } }; template <typename T> inline const T & base_obj(const T & t) { Q<T>::invoke(); return t; } template <typename T> std::pair<std::string,T*> make_nvp(const char * c, T & t) { return std::make_pair(c,&t); } int main() { int n = 0; make_nvp("int",base_obj(n)); std::cout << __PRETTY_FUNCTION__ << '\n'; return 0; } X::X(const Z & n) : m(n) { std::cout << __PRETTY_FUNCTION__ << '\n'; } X::~X() { std::cout << __PRETTY_FUNCTION__ << '\n'; } void X::reg(const X *) { std::cout << __PRETTY_FUNCTION__ << '\n'; }