Topic: Implementing auto_ptr
Author: kuehl@uzwil.rz.uni-konstanz.de (Dietmar Kuehl)
Date: 1995/09/08 Raw View
Hi,
Scott Meyers (smeyers@netcom.com) wrote:
: I've been trying to implement the auto_ptr template of section 20.4.5 of
: the draft standard, and, much to my surprise, this seems to be a compiler
: buster. Borland 4.51, MetaWare 3.3, and g++ 2.6.3 all generate errors
: either during compilation or linking.
First, here is an answer of your second question (whether there is a
compiler which can compile your code): The code only needs two minor
corrections to be compilable with gcc-2.7.0 (you can try gcc-2.7.0, in
fact presumably the newest announced version of gcc, using the
following URL: http://www.informatik.uni-konstanz.de/~kuehl/gcc if you
haven't installed it on your local system). The changes needed are the
following:
- in auto_ptr.cc: the line
auto_ptr<Foo> p1 = new Foo(1, 2, 10);
has to be changed to read
auto_ptr<Foo> p1(new Foo(1, 2, 10));
because the original line is illegal due to the explicit conversion
(see class.conv.ctor verse 2 of the DWP)
- in the implementation of auto_ptr<T>::operator=(auto_ptr<T>&) the class
name and a pair of parenthesis is missing. Thus it should read:
inline void auto_ptr<T>::operator=(auto_ptr<T> &rhs)
{ ptr = rhs.release(); }
: I have two questions. First, does the following implementation seem
: reasonable? The standard's description of the auto_ptr member functions is
: less that exemplary. For example, reset must return a pointer, but the
: standard doesn't say whether the old pointer value or the new pointer value
: is to be returned. I assume it's the old value. Also, the "Effects"
: clauses often say what functions are called, which seems an odd way to
: describe semantics. For example, the auto_ptr destructor is said to
: call the get() member function. I've assumed such statements are not
: implementation requirements, only semantic prescriptions.
I think your implementation is reasonable. The fact that the effects
are described using calls to other functions simply reduces the amount of
text needed to describe the semantics. Especially everytime 'get()' is
called is easier to describe than always saying something like "the
pointer 'p' specified as the the argument to the constructur
'auto_ptr(X* p)' or as the the argument to the most recent call to
'reset(X* p)'". The case of 'release()' and 'reset(X*)' (for both the
returned value is not defined although for 'release()' only the old
value makes sense) is something more difficult: There should really be
a useful definition which of the two pointers (the new or the old
value) is to be returned. Otherwise the returned value can never be
used savely anyway. I have some additional questions concerning this
clause:
- Why does 'operator=(auto_ptr&)' return a 'void' instead of the common
idiom to return a reference to the LHS: 'return *this'?
- Doesn't 'operator->() const' require that 'get() != 0' if 'm' is a
non-static member of 'X' (in the context of 'auto_ptr<X> &p; p->m')?
dk
--
http://www.informatik.uni-konstanz.de/~kuehl
dietmar.kuehl@uni-konstanz.de
I am a realistic optimist - that's why I appear to be slightly pessimistic
---
[ comp.std.c++ is moderated. Submission address: std-c++@ncar.ucar.edu.
Contact address: std-c++-request@ncar.ucar.edu. The moderation policy
is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]
Author: fjh@munta.cs.mu.OZ.AU (Fergus Henderson)
Date: 1995/09/10 Raw View
Michael Cook <mcook@cognex.com> writes:
>I've been using auto_ptr with g++ (a 2.6 dialect). G++ generates bogus
>warnings for certain expressions, but compiles the code correctly.
>
>The code it complains about is this:
>
> auto_ptr<V> byValue(auto_ptr<V> a);
> a = byValue(b);
> // warning: initialization of non-const `auto_ptr<V> &' from
> // rvalue `auto_ptr<V>'.
>
>It doesn't quite seem to like the fact that the copy-assignment and copy-ctor
>operators take non-const parameters.
That warning is not bogus; on the contrary, the code is ill-formed,
and the draft standard *requires* a diagnostic.
(5.2.2/3 says that argument passing is treated as initialization,
and 8.5.3/8 says you can't initialize a non-const reference with
an rvalue.)
--
Fergus Henderson | #define x t=a[i],a[i]=a[m],a[m]=t
| char a[]=" 12345678";main(m,i,j,t){for(i=m;i<
fjh@cs.mu.oz.au | 9;x,i++)for(x,j=m;--j?(t=a[m-j]-a[m])-j&&t+j:
http://www.cs.mu.oz.au/~fjh | main(m+1)*0;);m-9||puts(a+1);} /* 8 queens */
---
[ comp.std.c++ is moderated. Submission address: std-c++@ncar.ucar.edu.
Contact address: std-c++-request@ncar.ucar.edu. The moderation policy
is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]
Author: Michael Cook <mcook@cognex.com>
Date: 1995/09/10 Raw View
>>>>> "SM" == Scott Meyers <smeyers@netcom.com> writes:
SM> I've been trying to implement the auto_ptr template of section 20.4.5 of
SM> the draft standard, and, much to my surprise, this seems to be a compiler
SM> buster. Borland 4.51, MetaWare 3.3, and g++ 2.6.3 all generate errors
SM> either during compilation or linking.
I've been using auto_ptr with g++ (a 2.6 dialect). G++ generates bogus
warnings for certain expressions, but compiles the code correctly.
The code it complains about is this:
auto_ptr<V> byValue(auto_ptr<V> a);
a = byValue(b);
// warning: initialization of non-const `auto_ptr<V> &' from
// rvalue `auto_ptr<V>'.
It doesn't quite seem to like the fact that the copy-assignment and copy-ctor
operators take non-const parameters.
SM> For example, reset must return a pointer, but the standard doesn't say
SM> whether the old pointer value or the new pointer value is to be returned.
SM> I assume it's the old value.
Hmm. I assumed it was the the new value. I probably made that assumption
because `reset' is similar to `operator=', and in expressions like `a=b', the
"value returned" is the new value.
The problem I had with the standard's description of reset was that it left
unspecified (unmentioned) what should happen if you did
a = a;
Because programmers generally try to make that work right, I implemented
`reset' like this:
X* reset(X* p = 0)
{
if (p != p_)
{
delete p_;
p_ = p;
}
return p_;
}
SM> Also, the "Effects" clauses often say what functions are called, which
SM> seems an odd way to describe semantics. For example, the auto_ptr
SM> destructor is said to call the get() member function. I've assumed such
SM> statements are not implementation requirements, only semantic
SM> prescriptions.
Because `get()' is non-virtual, it shouldn't matter. They were probably only
trying to say, "the dtor acts as if you had invoke `delete' on the value
returned from `get()'".
SM> Here's my tentative implementation. It is untested, because I can't get
SM> any compiler to generate an executable using it:
What kinds of errors did you get?
SM> template<class T>
SM> inline void operator=(auto_ptr<T>& rhs)
SM> { ptr = rhs.release; }
You have a typo.
{ ptr = rhs.release(); }
And you need to scope your function:
inline void auto_ptr<T>::operator=(auto_ptr<T>& rhs)
SM> int main()
SM> {
SM> auto_ptr<Foo> p1 = new Foo(1, 2, 10);
G++ didn't like that last line. It says it can't convert `Foo*' to
`auto_ptr<Foo>&'. G++ accepted this, though:
auto_ptr<Foo> p1 (new Foo(1, 2, 10));
(I think those two constructs are supposed to be equivalent.)
I made those changes, and g++ compiled your code.
Michael.
---
[ comp.std.c++ is moderated. Submission address: std-c++@ncar.ucar.edu.
Contact address: std-c++-request@ncar.ucar.edu. The moderation policy
is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]
Author: Michael Cook <mcook@cognex.com>
Date: 1995/09/11 Raw View
>>>>> "FH" == Fergus Henderson <fjh@munta.cs.mu.OZ.AU> writes:
FH> That warning is not bogus; on the contrary, the code is ill-formed,
FH> and the draft standard *requires* a diagnostic.
FH> (5.2.2/3 says that argument passing is treated as initialization,
FH> and 8.5.3/8 says you can't initialize a non-const reference with
FH> an rvalue.)
Hmm. Interesting. That means the auto_ptr class can't be used that way.
That surprises me.
Thanks.
Michael.
---
[ comp.std.c++ is moderated. Submission address: std-c++@ncar.ucar.edu.
Contact address: std-c++-request@ncar.ucar.edu. The moderation policy
is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]
Author: veldhuis@xs4all.nl
Date: 1995/09/11 Raw View
:>- Why does 'operator=(auto_ptr&)' return a 'void' instead of the common
:> idiom to return a reference to the LHS: 'return *this'?
See also an earlier message of me. I think the assignment kills the right
hand side of an expression, so when it returns a copy and assigns that to
another auto_ptr it will also be invalid. It is possible I misunderstood the
message of Scott, but to me it seemed that
SM> template<class T>
SM> inline void auto_ptr<T>::operator=(auto_ptr<T>& rhs)
SM> { if (this != &rhs) reset(rhs.release()); }
releases the memory from the rhs instance, therefore
a = b = c will release memory from b and c and make the statement do
something else as we expect. I just hope I am wrong here.
with regards,
Wim Veldhuis
---------------------------------------------------
| Written with NeoLogic News for OS/2 |
---------------------------------------------------
| Unregistered copy with 10 days of use remaining |
---------------------------------------------------
---
[ comp.std.c++ is moderated. Submission address: std-c++@ncar.ucar.edu.
Contact address: std-c++-request@ncar.ucar.edu. The moderation policy
is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]