[C++-sig] return_internal_reference and implicitly_convertible danger
Raoul Gough
RaoulGough at yahoo.co.uk
Tue Sep 16 18:16:48 CEST 2003
Not sure if it's worth looking into this in any depth, but I've
discovered that implicitly_convertible and return_internal_reference
can combine in a nasty way. If I have a function exposed to Python
like this:
IntWrapper const *bar (IntWrapper const &i) {
return &i;
}
// ...
implicitly_convertible<int, IntWrapper> ();
def ("bar", bar, return_internal_reference<>());
then calling bar(IntWrapper(3)) is OK, but bar(3) returns a dangling
reference:
>>> print bar(IntWrapper(3))
3
>>> print bar(3)
1243312
I suspect there is a problem because the implicit conversion is
happening in C++, and that object gets destroyed prematurely (maybe
because the Python function call infrastructure doesn't have a
reference to it).
BTW, I'm not claiming that this client code should work! Then again,
maybe there's an easy way to catch this in the library that I don't
know about. Actual test code follows for completeness.
#include <boost/python/def.hpp>
#include <boost/python/class.hpp>
#include <boost/python/module.hpp>
#include <boost/python/implicit.hpp>
#include <sstream>
#include <string>
struct IntWrapper {
int mI;
IntWrapper (int i) : mI (i) { }
std::string repr () const {
std::stringstream temp;
temp << mI;
return temp.str();
}
};
IntWrapper const *bar (IntWrapper const &i) {
return &i;
}
BOOST_PYTHON_MODULE (testint) {
using namespace boost::python;
implicitly_convertible<int, IntWrapper> ();
class_<IntWrapper> ("IntWrapper", init<int>())
.def ("__repr__", &IntWrapper::repr);
def ("bar", bar, return_internal_reference<>());
}
--
Raoul Gough.
(setq dabbrev-case-fold-search nil)
More information about the Cplusplus-sig
mailing list