The ISO C++ standard in section 20.4.5.3 defines the effects and postconditions of auto_ptr conversions. It says that template<class Y> operator auto_ptr_ref<Y>() throw(); returns "an auto_ptr_ref<Y> that holds *this". Unlike the other conversions in the same section, there is no call to release(), so after the call the original auto_ptr should still own the memory. The following testcase is based on one from a testing group within IBM (not a customer-reported problem). It shows that creating a reference to an auto_ptr releases the memory from that auto_ptr when it should not. I see this behavior on powerpc*-linux for GCC 3.3 and later. I haven't tried earlier versions. ------------------------------------------------------------------------ // Test the effects and postconditions of auto_ptr conversions, defined // in the ISO C++ standard in section 20.4.5.3. #include <memory> extern "C" void abort (void); int failures = 0; #ifdef DBG #include <iostream> #define FAILURE(m) \ { \ std::cout << "line " << __LINE__ << ": " << m << std::endl; \ failures++; \ } #else #define FAILURE(m) { failures++; } #endif struct X { }; int main () { X* xptr = new X; std::auto_ptr<X> ap1 (xptr); if (ap1.get() != xptr) FAILURE ("ap1 does not own the memory") // Construct a reference to ap1; there should be no release. std::auto_ptr_ref<X> ref (ap1.operator std::auto_ptr_ref<X> ()); if (ap1.get() != xptr) FAILURE ("ap1 no longer owns the memory after constructing a reference") // Construct ap2 from the reference. ap2 should now own the memory // and ap1 should no longer hold it. std::auto_ptr<X> ap2(ref); if (ap2.get() != xptr) FAILURE ("ap2 does not own the memory after constructing from reference") if (ap1.get() != (X*)0) FAILURE ("ap1 is not zeroed after constructing ap2 from reference") if (failures != 0) abort (); return 0; } ------------------------------------------------------------------------ elm3b145% /opt/gcc-nightly/trunk/bin/g++ -DDBG bug.cc elm3b145% LD_LIBRARY_PATH=/opt/gcc-nightly/trunk/lib ./a.out line 34: ap1 no longer owns the memory after constructing a reference Aborted
Note that auto_ptr is deprecated for the next Standard, replaced by unique_ptr (which we deliver in C++0x mode). In fact the specifications of auto_ptr are known to be irreparably broken. That means we must be *extremely* careful here, if we touch the code we can destabilize an already brittle behavior. Do we have evidence that other widespread implementations actually behave differently than libstdc++-v3 here?
I assume that the person who sent me the test did so because it passes with some other implementation, but that doesn't mean it's widespread. It's fine with me if you say it won't be fixed.
Please, double check that, if possible. Then we'll see... By the way, we are essentially following Josuttis' implementation, in his book.
Paolo, the person who reported the problem to me is no longer with IBM. I've asked others in the same group to provide information about the origins of the test and what implementations are known to pass it, but it might take a long time to get that info.
Ok, take your time. For the reasons we already discussed we don't want to rush on this, in the meanwhile I will also try to collect more information.
The original testcase is from outside IBM and is probably run by many library implementors. That doesn't necessarily mean that many implementations pass this test.
At this point, I don't think we are going to do change the deprecated auto_ptr, so closing as WONTFIX.