Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > auto_ptr explained

Reply
Thread Tools

auto_ptr explained

 
 
Andrew
Guest
Posts: n/a
 
      12-03-2005
Hello all:
After spending some time figuring out auto_ptr class' implementation, I
decided to write a small article detailing its use of the auto_ptr_ref
proxy class to enable construction and assignment from temporaries. I
have placed the manuscript at:

http://www.nd.edu/~ahenrick/auto_ptr.pdf

It develops the problem and its solution in an incremental manner,
which will hopefully make it accessible for most people without being
too tedious.

Let me know if this was of use to you,
Andrew

 
Reply With Quote
 
 
 
 
roberts.noah@gmail.com
Guest
Posts: n/a
 
      12-04-2005

Andrew wrote:
> Hello all:
> After spending some time figuring out auto_ptr class' implementation, I
> decided to write a small article detailing its use of the auto_ptr_ref
> proxy class to enable construction and assignment from temporaries. I
> have placed the manuscript at:
>
> http://www.nd.edu/~ahenrick/auto_ptr.pdf
>
> It develops the problem and its solution in an incremental manner,
> which will hopefully make it accessible for most people without being
> too tedious.


This is actually a pretty interesting article. I haven't read it all
but it was going good. I've saved it in my read folder where things I
want to read go....and yes, I usually read them.

 
Reply With Quote
 
 
 
 
Jonathan Mcdougall
Guest
Posts: n/a
 
      12-05-2005
Andrew wrote:
> Hello all:
> After spending some time figuring out auto_ptr class' implementation, I
> decided to write a small article detailing its use of the auto_ptr_ref
> proxy class to enable construction and assignment from temporaries. I
> have placed the manuscript at:
>
> http://www.nd.edu/~ahenrick/auto_ptr.pdf
>
> It develops the problem and its solution in an incremental manner,
> which will hopefully make it accessible for most people without being
> too tedious.
>
> Let me know if this was of use to you,
> Andrew


1
==
"The diffculties surrounding the auto ptr class arise primarily due to
meaning of
the const qualifier"

The main difficulty with std::auto_ptr is with ownership transfer, not
the "const
qualifier".

"// auto_ptr specialization for ints
int* dumb_ptr = new int(0);
auto_ptr i = new int(0); // i points to *dumb_ptr
auto_ptr j(i); // j points to *dumb_ptr but i points to 0"

When you give examples, try to make them valid. For small examples
(this one may
qualify), you may omit main(), but you should definitely delete
dump_ptr. And I don't
think dump_ptr adds anything to your example.

"Well, for starters, the default declaration of the copy constructor is
auto_ptr(const auto_ptr& rhs);"

This is not the "default" declaration, it is the recommended one for
most uses.

"From a language standpoint, illegal copy construction of a const auto
ptr is
something which is better supported than the legal copy construction
from a
non-const auto ptr."

This makes no sense. You could say that because C++ prohibits binding a
non-const
reference to an rvalue, having a non-const parameter in the copy
constructor limits
its use.

1.1
===
"This is to prevent programmers from unintentionally trying to
manipulate temporaries which are invalid after the end of the scoping
statement:

double& dr = std::sin(2.0); // ERROR in standard C++
dr + 2;"

This is partly wrong and too restrictive. You could say that this is to
prevent
programmers from modifying an rvalue (not a temporary) when it would
make no sense
to modify it.

The rule about references is not about temporaries, but rvalues.
rvalues are
temporaries, but not all temporaries are rvalues. For example, an
exception is a
temporary and may be bound to a non-const reference; it is not an
rvalue. You should
modify this in the whole document.

"Thus, the next statement tries to reference a variable which is
invalid;"

which is illegal, not "invalid" (which means nothing).

2
==
You examples are badly formatted. Add more spaces.

"1. This is a specialization for ints, not a template."

The word "specialization" is usually used in relation to a template, so
I would say
that this classes explicitly uses an int* as the pointee type instead.

" 3. I have added messaging to cerr to follow program execution."

Don't. Use std::clog instead.

"4. Function definitions are included in the class definition (see 2nd
footnote)."

This is usually the case actually, because std::auto_ptr is a template.

"5. I have change [..]

"changed", not "change".

2.1
===
"This is returned as a the temporary object with address ending in
ab0."

Remove the "a".

3
=
"First, in considering operator=, we note that, because assignment
changes ownership
of both arguments, it is forbidden that either argument is a const auto
ptr"

operator= only has one argument (it is not specified how the this
pointer is passed). It would be more accurate to say that it is
forbidden that either the argument or the object on which operator= is
called is const.

"auto_ptr& operator= (auto_ptr& rhs)
{
reset(rhs.release());
return *this;
std::cerr << this << "auto_ptr assigned from " << &rhs << std::endl;
}

auto_ptr& operator= (const auto_ptr_ref& rhs) throw()
{
reset(rhs.yp);
return *this;
std::cerr << this << " auto_ptr assigned from " << &rhs
<< " : auto_ptr_ref -> auto_ptr" << std::endl;
}"

Both std::cerr statements are unreachable. You would have seen it if
you had formatted
the code correctly.

"auto_ptr j();
j = source();"

j is a function returning an auto_ptr here.

4
==
"Thus far the discussion has been independent of template
meta-programming:"

Rephrase that.

"both the problem and its solution are straight forward object-oriented
C++."

Templated code is not "straight forward object-oriented C++"?


Pretty good stuff, bravo.


Jonathan

 
Reply With Quote
 
Andrew
Guest
Posts: n/a
 
      12-05-2005
Jonathan Mcdougall wrote:

> "The diffculties surrounding the auto ptr class arise primarily due to
> meaning of the const qualifier"
>
> The main difficulty with std::auto_ptr is with ownership transfer, not
> the "const qualifier".


Point taken; but this article is not directly about ownership transfer.
It is about the use of auto_ptr_ref proxy class to prevent copy
construction or copy assignment of a const auto_ptr.

> "// auto_ptr specialization for ints
> int* dumb_ptr = ...
>
> When you give examples, try to make them valid....


Thanks -- corrected

> "Well, for starters, the default declaration of the copy constructor is
> auto_ptr(const auto_ptr& rhs);"
>
> This is not the "default" declaration, it is the recommended one for
> most uses.


I have provided a couple of references.

> "From a language standpoint, illegal copy construction...
>
> This makes no sense...


Thanks, I have changed the sentence

> "This is to prevent programmers from unintentionally trying to
> manipulate temporaries which are invalid after the end of the scoping
> statement:
>
> double& dr = std::sin(2.0); // ERROR in standard C++
> dr + 2;"
>
> This is partly wrong and too restrictive. You could say that this is to
> prevent programmers from modifying an rvalue...


I will refrain from introducing lvalue/rvalue terms in this article
because the terms themselves do not appear to be uniformly understood
by the C++ community (just search this newsgroup for instance).
Temporary objects, are, on the other hand, trivial to understand.

> The rule about references is not about temporaries, but rvalues...
> You should modify this in the whole document.


I do not understand your comment here. This concept is taken almost
straight out of Stroustrup's book, as cited on pg. 98: "References to
variables and referenced to constants are distinguished because the
introduction of a temporary in the case of variable is highly
error-prone;..."

If you can point out what is wrong or too restrictive with this
statement, I will fix it. As it stands, it may not be complete, but it
certainly is correct.

> "Thus, the next statement tries to reference a variable which is
> invalid;"
>
> which is illegal, not "invalid" (which means nothing).


Thanks, better worded now...

> You examples are badly formatted. Add more spaces.


IMHO, they are fine. If you can make a specific suggestion, that would
help.

> The word "specialization" is usually used in relation to a template,
> so I would say that this classes explicitly uses an int* as the pointee
> type instead.


That is true, but auto_ptr is normally implemented as a template. I
think the meaning is clear.

> " 3. I have added messaging to cerr to follow program execution."
>
> Don't. Use std::clog instead.


I think that std::cerr is better for this, since it isn't buffered.

> "This is returned as a the temporary object with address ending in ab0."
>
> Remove the "a".


I'll keep referring to the addresses using 3 letters/numbers. Prevents
speaking of address 90.

> operator= only has one argument...


Thanks, see correction.

> Both std::cerr statements are unreachable....


Opps... that's embarrassing. Thanks -- corrected

> "auto_ptr j();
>
> j is a function returning an auto_ptr here.


Fixed

> "Thus far the discussion has been independent of template
> meta-programming:"
>
> Rephrase that.


OK

> Templated code is not "straight forward object-oriented C++"?


That is the point of the sentence.

> Pretty good stuff, bravo.
>
> Jonathan


Thanks, Jonathan, for reading my article and taking the time to send
me corrections. I think that it is much more clear now.

Andrew

 
Reply With Quote
 
Andrew
Guest
Posts: n/a
 
      12-05-2005
Jonathan Mcdougall wrote:

> The rule about references is not about temporaries, but rvalues.
> rvalues are temporaries, but not all temporaries are rvalues. For example, an
> exception is a temporary and may be bound to a non-const reference; it is not an
> rvalue.


> Jonathan


Jonathan:

I discovered some very interesting stuff about exceptions that explains
the behavior that you point out here. I found this information in
Scott Meyers book "More Effective C++." It is really a great book.

Item 12: Understand how throwing an exception differs from passing
a parameter or calling a virtual function.

On pg. 64-65, he writes: "A thrown object (which, as explained above,
is always
a temporary) may be caught by simple reference; it need not be caught
by
reference-to-const. Passing a temporary object to a non-const
reference parameter
is not allowed for function calls (see Item 19), but it is for
exceptions."

The reason for this seems to be related to the idea that "when you call
a function,
control eventually returns to the call site (unless the function fails
to return),
but when you throw an exception, control does not return to the throw
site."

I will add a footnote to the article to note this "exception" for
exceptions.

Sincerely,
Andrew

 
Reply With Quote
 
Jonathan Mcdougall
Guest
Posts: n/a
 
      12-05-2005
Andrew wrote:
> Jonathan Mcdougall wrote:
>
> > "The diffculties surrounding the auto ptr class arise primarily due to
> > meaning of the const qualifier"
> >
> > The main difficulty with std::auto_ptr is with ownership transfer, not
> > the "const qualifier".

>
> Point taken; but this article is not directly about ownership transfer.
> It is about the use of auto_ptr_ref proxy class to prevent copy
> construction or copy assignment of a const auto_ptr.


I know, but it is a weird way to begin an article. You could say that
one of the difficulties in understanding the implementation of
std::auto_ptr is how it works with const instances, or something like
that.

> > "Well, for starters, the default declaration of the copy constructor is
> > auto_ptr(const auto_ptr& rhs);"
> >
> > This is not the "default" declaration, it is the recommended one for
> > most uses.

>
> I have provided a couple of references.


I misunderstood the statement, sorry.

> > "This is to prevent programmers from unintentionally trying to
> > manipulate temporaries which are invalid after the end of the scoping
> > statement:
> >
> > double& dr = std::sin(2.0); // ERROR in standard C++
> > dr + 2;"
> >
> > This is partly wrong and too restrictive. You could say that this is to
> > prevent programmers from modifying an rvalue...

>
> I will refrain from introducing lvalue/rvalue terms in this article
> because the terms themselves do not appear to be uniformly understood
> by the C++ community (just search this newsgroup for instance).
> Temporary objects, are, on the other hand, trivial to understand.


...but are not the same thing. The choice is yours to make: either be
correct wrt the standard, or use widespread terms. I would suggest
using the correct terms, while adding a note about the common usage (an
rvalue is commonly called a temporary...).

> > The rule about references is not about temporaries, but rvalues...
> > You should modify this in the whole document.

>
> I do not understand your comment here. This concept is taken almost
> straight out of Stroustrup's book, as cited on pg. 98: "References to
> variables and referenced to constants are distinguished because the
> introduction of a temporary in the case of variable is highly
> error-prone;..."


This is true, but it is only an example. It may make sense for some
temporaries (such as exceptions) to be modified, so not all temporaries
may not be bound to a non-const reference.

Although it may be valid to modify some temporaries (because they are
not, for example, in a readonly area in memory), such as

void f(int &i);

int main()
{
f(int(3));
}

it is forbidden because it is usually a semantic error (if f() takes a
non-const reference, this is because it is meant to be modified and
"sent back" to the user).

> If you can point out what is wrong or too restrictive with this
> statement, I will fix it. As it stands, it may not be complete, but it
> certainly is correct.


I should have said that it is partly wrong *because* is too
restrictive. "This is to prevent.." should at least be "This is to
prevent, for example, ...". However, temporaries created by a function
returning something else than a reference *are* rvalues, so your
example is indeed correct.

You explicitly talk about temporaries throughout the whole document,
but standard-wise, it is wrong. rvalues, not temporary objects, may not
be bound to non-const references. Some rvalues are temporaries and some
temporaries are rvalues.

> > You examples are badly formatted. Add more spaces.

>
> IMHO, they are fine. If you can make a specific suggestion, that would
> help.


auto_ptr(const auto_ptr_ref& rhs) throw() : ap(rhs.yp)
{ std::cerr << this << " auto_ptr constructed from " << &rhs
<< " : auto_ptr_ref -> auto_ptr" << std::endl; }

should be

auto_ptr(const auto_ptr_ref& rhs) throw()
: ap(rhs.yp)
{
std::cerr << this << " auto_ptr constructed from " << &rhs
<< " : auto_ptr_ref -> auto_ptr" << std::endl;
}

or something along these lines. Whitespace is important, especially in
a tutorial/article/whatever you call something meant to teach. Though
there may be differences between our coding conventions, the code
should be easy to read and, imo, it is not.

> > " 3. I have added messaging to cerr to follow program execution."
> >
> > Don't. Use std::clog instead.

>
> I think that std::cerr is better for this, since it isn't buffered.


By convention, std::cerr is used in case something bad happened and
must be reported. Since it is not buffered, system calls are made for
each output, making it more likely to appear but slowing the
application because system calls are usually expensives. Buffered
streams may not be flushed if the application terminates unexpectedly.

Since these log messages are not vital to the execution, they should go
to a buffered stream, such as std::cout or std::clog. Since std::cout
is usually used for "normal" output, std::clog is the way to go. It is
also easier to redirect logging and errors to different streams, such
as files or different output devices.

Note that is a convention, but, imo, conventions are better followed,
event in small programs.

> > "This is returned as a the temporary object with address ending in ab0."
> >
> > Remove the "a".

>
> I'll keep referring to the addresses using 3 letters/numbers. Prevents
> speaking of address 90.


I understand that, but I don't get what the "a" is. I think "This is
returned as the temporary object with address ending in ab0" makes more
sense, but there may be something I don't understand.

> > Templated code is not "straight forward object-oriented C++"?

>
> That is the point of the sentence.


And what else is not part of "straight forward object-oriented C++"?


Jonathan

 
Reply With Quote
 
Andrew
Guest
Posts: n/a
 
      12-06-2005
I recently updated the article online.

Thanks again for your recent reply Jonathan. I will try to think of a
better opening sentence for the article. I have incorporated a lot of
your changes. Some things of which I still am uncertain are:

1. It seems to me that the standard does a pretty good job of *not*
defining precisely what lvalues and rvalues are. I have avoided
them because they are confusing -- and unnecessarily so for this
article. If you can provide me with the standards definitions of these
terms, and perhaps a way to show that the auto_ptr class needs to
make such a distinction, I will do so. Temporaries are the way that
Stroustrup describes this kind of behavior and that is good enough for
me.

2. I still do not understand why my referring to the temporary object
"ab0" is bad. Please elaborate.

3. I think that we are saying the same thing about the first sentence
in Sect. 4. I do not consider templates or generic programming a part
of OO C++. That is the point of not using templates until this point
in the article, and by the opening of Sect. 4, the role of auto_ptr_ref
has been completely explained. Thus, before I began templatizing
the class, both the problem and its solution are really finished.
My purpose is simply to show that templates really don't play a role
in getting auto_ptr to work right.

Now Sect. 4 does go over some pit-falls of templates, but they do
not affect how auto_ptr_ref is used to enable construction from
temporaries.

Does that make sense?

Sincerely,
AKH

 
Reply With Quote
 
Jonathan Mcdougall
Guest
Posts: n/a
 
      12-06-2005
Andrew wrote:
> I recently updated the article online.


Please quote the message you are answering to next time.

> Thanks again for your recent reply Jonathan. I will try to think of a
> better opening sentence for the article. I have incorporated a lot of
> your changes.


Yes, I saw them.

> Some things of which I still am uncertain are:
>
> 1. It seems to me that the standard does a pretty good job of *not*
> defining precisely what lvalues and rvalues are. I have avoided
> them because they are confusing -- and unnecessarily so for this
> article. If you can provide me with the standards definitions of these
> terms,


Sections 3.10 and 12.2 do the job.

> and perhaps a way to show that the auto_ptr class needs to
> make such a distinction, I will do so. Temporaries are the way that
> Stroustrup describes this kind of behavior and that is good enough for
> me.


So be it.

> 2. I still do not understand why my referring to the temporary object
> "ab0" is bad. Please elaborate.


Ok, we may not be talking about the same thing here. I was referring to
the "a" between the words "as" and "the".

"This is returned as a the temporary object with address ending in ab0
^^^

> 3. I think that we are saying the same thing about the first sentence
> in Sect. 4. I do not consider templates or generic programming a part
> of OO C++.


Yeah, I take back what I said. Templates are not part of
object-oriented programming. A procedural language could have
templates.

> That is the point of not using templates until this point
> in the article, and by the opening of Sect. 4, the role of auto_ptr_ref
> has been completely explained. Thus, before I began templatizing
> the class, both the problem and its solution are really finished.
> My purpose is simply to show that templates really don't play a role
> in getting auto_ptr to work right.


And it was a good idea since templates confuse many programmers. Using
a specific type allows one to concentrate on the problem.


Jonathan

 
Reply With Quote
 
Francis Glassborow
Guest
Posts: n/a
 
      12-06-2005
In article <(E-Mail Removed) .com>,
Jonathan Mcdougall <(E-Mail Removed)> writes
>> Point taken; but this article is not directly about ownership transfer.
>> It is about the use of auto_ptr_ref proxy class to prevent copy
>> construction or copy assignment of a const auto_ptr.

>
>I know, but it is a weird way to begin an article. You could say that
>one of the difficulties in understanding the implementation of
>std::auto_ptr is how it works with const instances, or something like
>that.



The mechanism that makes auto_ptr 'work' was invented under extreme time
pressure by a brilliant C++ programmer. It is so close to the edge of
what is allowed in C++ that even the majority of WG21 & J16 (The C++
standard's committees) were not entirely convinced that it was not over
the edge. However there was tacit agreement among implementors that they
would make it work and that a much better mechanism would be provided
for the next full version of C++.

Technically, because auto_ptr is in the Standard Library it can be made
to work by 'magic' i.e. by methods not available to ordinary
programmers.

The important thing to understand is that even though (because it is a
template) its implementation is exposed for all to see, it is not
something that the Standard's committees would encourage others to use,
or that they would happily support in future.

In general programmers are well advised to keep well away from the
bleeding edge.

--
Francis Glassborow ACCU
Author of 'You Can Do It!' see http://www.spellen.org/youcandoit
For project ideas and contributions: http://www.spellen.org/youcandoit/projects
 
Reply With Quote
 
Andrew
Guest
Posts: n/a
 
      12-07-2005
Francis Glassborow wrote:
> Technically, because auto_ptr is in the Standard Library it can be made
> to work by 'magic' i.e. by methods not available to ordinary
> programmers.


Hello Francis:

The reason I wrote the article was to de-mystify the auto_ptr class.
People simply kept saying "don't think about how it works; it's bad
C++ black-magic."

If you take a look at the article, it think that I have made it pretty
clear that there is nothing magic in auto_ptr; although, I do think
that both the problem and the solution are less than self-explanatory.

There is also nothing magic in the way that gcc implements auto_ptr;
its standard C++. If particular implementations of the STL do
something weird to get auto_ptr to work in a particular way, that is
there choice...

I really do think that someone can learn some very important and
interesting things by looking at the auto_ptr class; even though the
Colvin/Gibbins' trick is a bit esoteric. The article tries to
point these out as they become naturally relevant to auto_ptr's
design.

Thanks,
AKH

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
explicit auto_ptr<T>::auto_ptr(T*) ? Sousuke C++ 9 03-16-2010 11:54 AM
SIP 101 - Session Initiation Protocol Explained Silverstrand Front Page News 0 07-29-2005 05:31 PM
Case Study: Backups Explained Silverstrand Front Page News 0 06-24-2005 09:29 PM
auto_ptr<Derived> to auto_ptr<Base> Siemel Naran C++ 2 01-11-2005 04:45 AM
Where on CCO is the complete config register explained?? Brad Hill Cisco 3 07-23-2003 06:08 AM



Advertisments