Opened 13 years ago
Closed 13 years ago
#4003 closed Bugs (fixed)
Error in destroy.hpp when methods "T()" and "operator~()" are defined.
Reported by: | Owned by: | Dave Abrahams | |
---|---|---|---|
Milestone: | Boost 1.43.0 | Component: | python USE GITHUB |
Version: | Boost 1.42.0 | Severity: | Problem |
Keywords: | Cc: | cmbruns@… |
Description
I am wrapping a large library using boost python and Py++. I encountered a peculiar situation with one of the wrapped classes.
I have attached a minimal example and an imperfect patch (see below).
The problem occurs on line 33 of boost/python/detail/destroy.hpp:
unpatched version: ================= 30 template <class T> 31 static void execute(T const volatile* p) 32 { 33 p->T::~T(); 34 }
The problem is that the class being wrapped has a member function "T()", and the class returned by that function has an "operator~()"; which leads to a compile error. I have been working around this for the past year by patching the file destroy.hpp to use the name "Type" instead of "T" in this section, each time I install a new version of boost.
patched version: =============== 30 template <class Type> 31 static void execute(Type const volatile* p) 32 { 33 p->Type::~Type(); 34 }
That's not a complete solution, of course. I suspect I could concoct another scenario with classes that have a "Type" method etc. But it solves the problem for me with the libraries I am actually wrapping. Perhaps you C++ gurus could come up with a more robust approach.
With the patch in place, my module compiles. Without the patch, I get these compiler messages:
############################################################# building 'foo_module' extension C:\Program Files\Microsoft Visual Studio 9.0\VC\BIN\cl.exe /c /nologo /Ox /MD /W3 /GS - /DNDEBUG "-IC:/Program Files/boost/boost_1_42" -I. -Ic:\Python26\include -Ic:\Pytho n26\PC /Tpwrap_foo.cpp /Fobuild\temp.win32-2.6\Release\wrap_foo.obj /EHsc -D"_HAS_TR1 =0" wrap_foo.cpp C:/Program Files/boost/boost_1_42\boost/python/detail/destroy.hpp(33) : error C2523: 'Foo3::~T' : destructor tag mismatch
C:/Program Files/boost/boost_1_42\boost/python/detail/destroy.hpp(95) : see reference to function template instantiation 'void boost::python::detail::value_destroyer<false>::execute<const T>(volatile const T *)' being compiled with [
T=const Foo3
] C:/Program Files/boost/boost_1_42\boost/python/detail/destroy.hpp(101) : see reference to function template instantiation 'void boost::python::detail::destroy_referent_impl<T>(void *,T &(cdecl *)(void))' being compiled with [
T=const Foo3
] C:/Program Files/boost/boost_1_42\boost/python/converter/rvalue_from_python_data.hpp(135) : see reference to function template instantiation 'void boost::python::detail::destroy_referent<const Foo3&>(void *,T (cdecl *)(void))' being compiled with [
T=const Foo3 &
] C:/Program Files/boost/boost_1_42\boost/python/converter/rvalue_from_python_data.hpp(133) : while compiling class template member function 'boost::python::converter::rvalue_from_python_data<T>::~rvalue_from_python_data(void)' with [
T=const Foo3 &
] C:/Program Files/boost/boost_1_42\boost/python/converter/arg_from_python.hpp(124) : see reference to class template instantiation 'boost::python::converter::rvalue_from_python_data<T>' being compiled with [
T=const Foo3 &
] C:/Program Files/boost/boost_1_42\boost/python/arg_from_python.hpp(27) : see reference to class template instantiation 'boost::python::converter::arg_rvalue_from_python<T>' being compiled with [
T=const Foo3 &
] C:/Program Files/boost/boost_1_42\boost/preprocessor/iteration/detail/local.hpp(37) : see reference to class template instantiation 'boost::python::arg_from_python<T>' being compiled with [
T=const Foo3 &
] C:/Program Files/boost/boost_1_42\boost/python/detail/caller.hpp(200) : while compiling class template member function 'PyObject *boost::python::detail::caller_arity<2>::impl<F,Policies,Sig>::operator ()(PyObject *,PyObject *)' with [
F=void (thiscall Foo4::* )(const Foo3 &), Policies=boost::python::default_call_policies, Sig=boost::mpl::vector3<void,Foo4 &,const Foo3 &>
] C:/Program Files/boost/boost_1_42\boost/python/detail/caller.hpp(169) : see reference to class template instantiation 'boost::python::detail::caller_arity<2>::impl<F,Policies,Sig>' being compiled with [
F=void (thiscall Foo4::* )(const Foo3 &), Policies=boost::python::default_call_policies, Sig=boost::mpl::vector3<void,Foo4 &,const Foo3 &>
] C:/Program Files/boost/boost_1_42\boost/python/make_function.hpp(61) : see reference to class template instantiation 'boost::python::detail::caller<F,CallPolicies,Sig>' being compiled with [
F=void (thiscall Foo4::* )(const Foo3 &), CallPolicies=boost::python::default_call_policies, Sig=boost::mpl::vector3<void,Foo4 &,const Foo3 &>
] C:/Program Files/boost/boost_1_42\boost/python/make_function.hpp(146) : see reference to function template instantiation 'boost::python::api::object boost::python::detail::make_function_aux<F,CallPolicies,Signature,boost::mpl::int_<N>>(F,const CallPolicies &,const Sig &,const boost::python::detail::keyword_range &,NumKeywords)' being compiled with [
F=void (thiscall Foo4::* )(const Foo3 &), CallPolicies=boost::python::default_call_policies, Signature=boost::mpl::vector3<void,Foo4 &,const Foo3 &>, N=1, Sig=boost::mpl::vector3<void,Foo4 &,const Foo3 &>, NumKeywords=boost::mpl::int_<1>
] C:/Program Files/boost/boost_1_42\boost/python/class.hpp(544) : see reference to function template instantiation 'boost::python::api::object boost::python::make_function<Fn,boost::python::default_call_policies,T1,boost::mpl::vector3<T0,Foo4 &,T2>>(F,const CallPolicies &,const Keywords &,const Signature &)' being compiled with [
Fn=void (thiscall Foo4::* )(const Foo3 &), T1=boost::python::detail::keywords<1>, T0=void, T2=const Foo3 &, F=void (thiscall Foo4::* )(const Foo3 &), CallPolicies=boost::python::default_call_policies, Keywords=boost::python::detail::keywords<1>, Signature=boost::mpl::vector3<void,Foo4 &,const Foo3 &>
] C:/Program Files/boost/boost_1_42\boost/python/class.hpp(614) : see reference to function template instantiation 'void boost::python::class_<W>::def_impl<Foo4,Fn,boost::python::detail::def_helper<T1>>(T *,const char *,Fn,const Helper &,...)' being compiled with [
W=Foo4, Fn=void (thiscall Foo4::* )(const Foo3 &), T1=boost::python::detail::keywords<1>, T=Foo4, Helper=boost::python::detail::def_helper<boost::python::detail::keywords<1>>
] C:/Program Files/boost/boost_1_42\boost/python/class.hpp(244) : see reference to function template instantiation 'void boost::python::class_<W>::def_maybe_overloads<A1,A2>(const char *,Fn,const boost::python::detail::keywords<1> &,...)' being compiled with [
W=Foo4, A1=void (thiscall Foo4::* )(const Foo3 &), A2=boost::python::detail::keywords<1>, Fn=void (thiscall Foo4::* )(const Foo3 &)
] wrap_foo.cpp(21) : see reference to function template instantiation 'boost::python::class_<W> &boost::python::class_<W>::def<void(thiscall Foo4::* )(const Foo3 &),boost::python::detail::keywords<1>>(const char *,A1,const A2 &)' being compiled with [
W=Foo4, A1=void (thiscall Foo4::* )(const Foo3 &), A2=boost::python::detail::keywords<1>
]
error: command '"C:\Program Files\Microsoft Visual Studio 9.0\VC\BIN\cl.exe"' failed with exit status 2 #########################################################
Attachments (4)
Change History (10)
by , 13 years ago
comment:1 by , 13 years ago
Sorry about the two copies of wrap_foo.cpp. In my impatience I hit the "submit" button twice.
comment:2 by , 13 years ago
It seems to work if I change the code to
p->~T()
However, this is slightly different, since it will invoke a virtual destructor, where the original will not. The only other alternative I can think of it to mangle the name so that there is no chance of anyone using the same name. (i.e. template<class T_boost_python_unique_id_82623817364646282>)
comment:3 by , 13 years ago
Owner: | changed from | to
---|
Isn't using a virtual d'tor OK here?
What about a simple typedef either inside the function body or in the body of the class? Does VC still look up the wrong name?
follow-up: 5 comment:4 by , 13 years ago
Owner: | changed from | to
---|
I would assume that a virtual destructor is okay, but I didn't write the code in question. A typedef doesn't seem to help. The first name after the -> always seems to be looked up in the context of T first. I even tried this:
template<class T> struct Destroyer { typedef T Type; static void destroy(T* t) { t->Destroyer<Type>::Type::~Type(); } }; struct S { void Type(); void Destroyer(); }; int main() { S t; Destroyer<S>::destroy(&t); }
and it still fails.
comment:5 by , 13 years ago
Replying to steven_watanabe:
I would assume that a virtual destructor is okay, but I didn't write the code in question.
Feel free to check in your fix, preferably after having run the tests once :-)
comment:6 by , 13 years ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
minimized example header file to be wrapped