
On Fri, Oct 22, 2010 at 1:35 PM, Daniel Walker <daniel.j.walker@gmail.com> wrote:
Oops. Sorry, I spoke too soon. In fact, it IS currently possible for a boost::function object to become empty due to a failed assignment. It happens because the small object manager clones the target during a call to swap(). If there is an exception during the allocation, boost::function handles it, sets itself to empty and rethrows. Here's an example that demonstrates the behavior.
One more thing, for those who are interested. To make the example portable, you need to add a destructor to S1. Also, so as not to cause confusion, I should have had operator new actually allocate something. :P So, to reproduce the behavior the following is a complete example that works on msvc 10 and gcc 4.2. #include <cassert> #include <iostream> #include <boost/function.hpp> struct S0 { void operator()() {} }; int i = 0; struct S1 { ~S1() {} void operator()() {} void* operator new(std::size_t, void* p) { // throw on third alloc if(++i == 3) throw std::bad_alloc(); return p = ::new S1(); } }; int main() { boost::function<void()> g = S0(); assert(g); // assertion ok, since g is not empty. try { g = S1(); } catch(std::exception& e) { std::cerr << "failed function assignment: " << e.what() << std::endl; } assert(g); // now assert fails, since g is empty. return 0; } Daniel Walker