Topic: Something I don't understand about auto_ptr


Author: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 1999/03/02
Raw View
Siemel Naran wrote:
>
> On 01 Mar 99 18:32:59 GMT, Biju Thomas <bijuthom@ibm.net> wrote:
> >Siemel Naran wrote:
>
> >> This does not require std::auto_ptr to have a copy constructor.
>
> >This assumes that all compilers implement the unnamed return value
> >optimization which is not true.
>
> Indeed, you're right!  I forgot about the unnamed return value
> optimization.  An accessible copy constructor is still required,
> even if it is not used (ie, even if the compiler does the
> return value optimization).  The following program generates an
> error on egcs:
>
>    class X
>    {
>       public:
>          X();
>       private:
>          X(const X&);
>    };
>
>    X f() { return X(); } // LINE9
>
>
> The error is that on LINE9, "X::X(const X&)" is private.
>
> So disregard my earlier comments.  A copy constructor is required
> for std::auto_ptr if we are to return such objects.

Would the following work?

auto_ptr<int> foo()
{
  auto_ptr<int> ptr(new int);
  return ptr.release();
}

This would use auto_ptr<int>::auto_ptr(int*) - however, this
constructor is explicit, and I'm not sure if explicit
constructors can be called in constructing a return value.
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: James.Kanze@dresdner-bank.com
Date: 1999/03/02
Raw View
In article <36DA9DCF.2EF7A26D@ibm.net>,
  bijuthom@ibm.net wrote:
> Siemel Naran wrote:
> >
> > On 28 Feb 99 08:51:27 GMT, Francis Glassborow
> > >
> > >You miss the point, exactly how is the function doing the return going
> > >to manage to create a value to return, it needs a copy ctor.
> >
> > We normally return unnamed auto_ptr objects, as in create functions.
> >    std::auto_ptr<Base> read(std::istream& strm) {
> >       else if (s=="Derived1") return Result(new Derived1());
> [...]
> >    }
> > This does not require std::auto_ptr to have a copy constructor.
> >
>
> This assumes that all compilers implement the unnamed return value
> optimization which is not true.

The legality of a program does not depend on optimization.  Even
compilers implementing the unnamed return value optimization must verify
that there is an accessible copy constructor.

--
James Kanze                                           GABI Software, S   rl
Conseils en informatique orient    objet  --
                          --  Beratung in industrieller Datenverarbeitung
mailto: kanze@gabi-soft.fr          mailto: James.Kanze@dresdner-bank.com

-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/       Search, Read, Discuss, or Start Your Own


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Gabriel Dos_Reis <gdosreis@sophia.inria.fr>
Date: 1999/03/03
Raw View
sbnaran@bardeen.ceg.uiuc.edu (Siemel Naran) writes:

=B7---------------
| On 1 Mar 1999 21:33:49 GMT, Andrei Alexandrescu
|=20
| >One never stops learning. You made an interesting point I didn't know =
of.
| >I just wonder, is this standard behavior or just a peculiarity of
| >egcs? I'm asking that not because I don't believe you, but because you
| >didn't quote from the standard.
|=20
| The standard talks of the named and unnamed return value optimization.
| This means that there is such a thing as the named and unnamed return
| value un-optimization.  (IOW, if compiler had to do the return value
| optimization for unnamed objects, then why mention the concept of
| unnamed return value optimization?)
=B7---------------

Well, the Standard does NOT actually mention anything such as "concept=20
of unnamed return value optimization".=20
That optimization is derived from the first part of the _general_
disposition 12.8/15 which allows a compiler to optimize away a
copy-constructor call when copying temporary object using the
copy-constructor. It just happens that the construct=20

=B7---------------
| In the return value un-optimization,
|    { return T(); }
=B7---------------

falls in the scope of that optimization. OTOH the second part of
12.8/15 is more specialized and termed the "named return value
optimization" in the C++ community.

--=20
Gabriel Dos Reis, dosreis@cmla.ens-cachan.fr
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Gabriel Dos_Reis <gdosreis@sophia.inria.fr>
Date: 1999/03/03
Raw View
sbnaran@fermi.ceg.uiuc.edu (Siemel Naran) writes:

[...]

=B7----------------
| 1.
| We normally return unnamed auto_ptr objects, as in create functions.
|    std::auto_ptr<Base> read(std::istream& strm) {
|       std::string s;
|       strm >> s;
|       typedef std::auto_ptr<Base> Result;
|       if (false) ;
|       else if (s=3D=3D"Derived1") return Result(new Derived1());
|       else if (s=3D=3D"Derived2") return Result(new Derived2());
|       else throw CantCreate(s);
|    }
| This does not require std::auto_ptr to have a copy constructor.
=B7----------------

Can you explain why you think so?

=B7----------------

[...]

| We see that the return statement can't be written as "return out",
| but instead must be written as "return Result(out.release())".
|=20
|=20
| More importantly, snippet (2) can be written in the style of (1).
| That is, we can eliminate the named temporary 'out'.  The resulting
| code has greater locality of reference, and is therefore better:
|=20
|    std::auto_ptr<Thing> get(std::istream& strm) {
|       typedef std::auto_ptr<Thing> Result;   =20
|       std::string s;
|       strm >> s;
|       return Result(s=3D=3D"yes" ? (new Thing()) : 0);
|    }
=B7----------------

I don't buy this either. You miss an important point here: the copy
constructor must be accessible in order to copy out the value of the
return expression statement. Whether the return expression statement
names a local object or not is irrelevent. You have to return a value
so you need an accessible copy-constructor.

--=20
Gabriel Dos Reis, dosreis@cmla.ens-cachan.fr
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: James Kuyper <kuyper@wizard.net>
Date: 1999/03/03
Raw View
Gabriel Dos_Reis wrote:
>=20
> sbnaran@fermi.ceg.uiuc.edu (Siemel Naran) writes:
>=20
> [...]
>=20
> =B7-------------
> | Even for unnamed return?
> =B7-------------
>=20
> Yes, even for unnamed retunr value. See 12.8/14
>=20
> "Andrei Alexandrescu" <alexandrescua@micromodeling.com> writes:
>=20
> =B7-------------
> | One never stops learning. You made an interesting point I didn't know
> | of.
> | I just wonder, is this standard behavior or just a peculiarity of
> | egcs? I'm asking that not because I don't believe you, but because yo=
u
> | didn't quote from the standard.
> |
> | I think I'll derive something from auto_ptr, make the copy constructo=
r
> | private, and give it a shot in my next non-toy project.
> =B7-------------
>=20
> Optimizations are performed under the "as-if" rule. That means even
> if the copy-ctor call is optimized away---regardless of whether the
> return value is named or not---the semantics restrictions must apply.

The return-value optimization is not the result of the as-if rule. If
the copy constructor or the destructor keeps track of how many times
it's been called, a program can detect whether or not the optimization
has been done, so there is an observable difference, which prevents the
as-if rule from covering it.
It is section 12.8 p15 which explicitly allowe copy-ctor calls to be
dropped, even when doing so may have observable consequences:

"Whenever a temporary class of object is copied using a copy
constructor, and this object and the copy have the same cv-unqualified
type, an implmentation is permitted to treat the original and the copy
as two different ways of referring to the same object and not perform
the copy at all, even if the copy constructor or destructor have side
effects. For a function with a class return type, if the expression in
the return statement is the name of a local object, and the
cv-unqualified type of the local object is the same as the function
return type, an implementation is permitted to omit creating the
temporarty objec to hold the function return type, even if the class
copy constructor or destructor has side effects."
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Gabriel Dos_Reis <gdosreis@sophia.inria.fr>
Date: 1999/03/03
Raw View
James Kuyper <kuyper@wizard.net> writes:

[...]

| > Optimizations are performed under the "as-if" rule. That means even
| > if the copy-ctor call is optimized away---regardless of whether the
| > return value is named or not---the semantics restrictions must apply.
|
| The return-value optimization is not the result of the as-if rule. If
| the copy constructor or the destructor keeps track of how many times
| it's been called, a program can detect whether or not the optimization
| has been done, so there is an observable difference, which prevents the
| as-if rule from covering it.

Good point.

The Standard does indeed state that an implementation may
violate the "as-if" rule in specific cases (e.g the paragraph you
quote). Let me give it another try.


| It is section 12.8 p15 which explicitly allowe copy-ctor calls to be
| dropped, even when doing so may have observable consequences:
|
| "Whenever a temporary class of object is copied using a copy
| constructor, and this object and the copy have the same cv-unqualified

[...]


from this phrase it appears to me that for the implementation being
able to use the copy-constructor to copy the temporary object, that
copy-constructor must be accessible.


--
Gabriel Dos Reis, dosreis@cmla.ens-cachan.fr
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "Andrei Alexandrescu" <alexandrescua@micromodeling.com>
Date: 1999/02/26
Raw View
Hello,

This message is for auto_ptr addicts :o).
We all know a lot about the hard birth of auto_ptr. (See for instance
http://www.awl.com/cseng/titles/0-201-63371-X/auto_ptr.html).

AFAIK, the shift from version 1 to version 2 was made because the
following
code wasn't working:

auto_ptr<Something> f();
auto_ptr<Something> p1(f());   // error!  can't copy an auto_ptr
returned
                                             // from a function
auto_ptr<Something> p2;
p2 = f();    // error!  can't use an auto_ptr returned
                // from a function as the source of an assignment

This bothered people a lot for obvious reasons; what I don't
understand is why they didn't like this simple fix:

auto_ptr<Something> f();
auto_ptr<Something> p1(f().release());    // ok
auto_ptr<Something> p2;
p2 = f().release();    // ok

After thinking of it a bit, I liked the fix even better that the
auto_ptr_ref wizardry. You know why? Because the assignment/copy
construction of auto_ptr is anyway counter-intuitive because of the
destructive copy semantics. So the code above actually says much
clearer what's actually going on: a transfer of ownership.

The non-intuitive copy semantics of auto_ptr are the root of virtually
all criticisms to auto_ptr. Why not disabling copy/assignment altogether
and call release() on the fly for explicit ownership transfer?

Andrei



[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1999/02/27
Raw View
In article <36d6b99f.0@10.1.1.65>, Andrei Alexandrescu <alexandrescua@mi
cromodeling.com> writes
>The non-intuitive copy semantics of auto_ptr are the root of virtually
>all criticisms to auto_ptr. Why not disabling copy/assignment altogether
>and call release() on the fly for explicit ownership transfer?

Because people have legitimate reasons for returning an auto_ptr by
value.  That was the crunch issue.


Francis Glassborow      Chair of Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Jonathan Biggar <jon@floorboard.com>
Date: 1999/02/27
Raw View
Francis Glassborow wrote:
>
> In article <36d6b99f.0@10.1.1.65>, Andrei Alexandrescu <alexandrescua@mi
> cromodeling.com> writes
> >The non-intuitive copy semantics of auto_ptr are the root of virtually
> >all criticisms to auto_ptr. Why not disabling copy/assignment altogether
> >and call release() on the fly for explicit ownership transfer?
>
> Because people have legitimate reasons for returning an auto_ptr by
> value.  That was the crunch issue.

I think you missed his point.  Using release(), you can still return an
auto_ptr by value from a function and effectively assign the result to
another auto_ptr.  You just don't get it done automatically by the
compiler.  The programmer just has to explicitly call release() whenever
he transfers ownership.

It is more work for the programmer to call release() everywhere, but the
tradeoff is that ownership transfer would always be explicit, so the
code becomes more readable.

--
Jon Biggar
Floorboard Software
jon@floorboard.com
jon@biggar.org
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "Dave Abrahams" <abrahams@mediaone.net>
Date: 1999/02/28
Raw View
In article <36D82DA5.6A6D5180@floorboard.com> , Jonathan Biggar
<jon@floorboard.com>  wrote:

> I think you missed his point.  Using release(), you can still return an
> auto_ptr by value from a function and effectively assign the result to
> another auto_ptr.  You just don't get it done automatically by the
> compiler.  The programmer just has to explicitly call release() whenever
> he transfers ownership.
>
> It is more work for the programmer to call release() everywhere, but the
> tradeoff is that ownership transfer would always be explicit, so the
> code becomes more readable.

That's a matter of opinion. If you always pass auto_ptr by value, whenever
you see one it "means" transfer of ownership, which you could argue makes
the code more readable. Would code be more readable if the compiler always
required you to explicitly write destructor calls for automatic variables?
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "Andrei Alexandrescu" <alexandrescua@micromodeling.com>
Date: 1999/02/28
Raw View
Francis Glassborow wrote in message ...
>
>In article <36d6b99f.0@10.1.1.65>, Andrei Alexandrescu
<alexandrescua@mi
>cromodeling.com> writes
>>The non-intuitive copy semantics of auto_ptr are the root of
virtually
>>all criticisms to auto_ptr. Why not disabling copy/assignment
altogether
>>and call release() on the fly for explicit ownership transfer?
>
>Because people have legitimate reasons for returning an auto_ptr by
>value.  That was the crunch issue.


This doesn't answer to my question. You could return an auto_ptr by
value even if it lacked copy construction. All you had to do would
have been to call release() on the function return value:

auto_ptr<Something> p1(f().release());    // ok

Andrei




[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1999/02/28
Raw View
In article <36D82DA5.6A6D5180@floorboard.com>, Jonathan Biggar
<jon@floorboard.com> writes
>I think you missed his point.  Using release(), you can still return an
>auto_ptr by value from a function and effectively assign the result to
>another auto_ptr.  You just don't get it done automatically by the
>compiler.  The programmer just has to explicitly call release() whenever
>he transfers ownership.
>
>It is more work for the programmer to call release() everywhere, but the
>tradeoff is that ownership transfer would always be explicit, so the
>code becomes more readable.

I am pretty sure that does not work.  It leaves the raw pointer exposed
during the return process which is exactly what the proponents wanted to
avoid.  AFAIK the only way you can return by value is by calling a copy
ctor to copy a local object to the temporary for the return.

You have know idea how much time was put into trying to ensure that
auto_ptr met the design requirements of some while not supporting to
much dangerous behaviour.  You do not honestly think we would have
pushed so hard against the constraints of the language for any other
reason do you?


Francis Glassborow      Chair of Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: clamage@taumet.eng.sun.com (Steve Clamage)
Date: 1999/02/28
Raw View
Francis Glassborow wrote in message ...
>In article <36d86c59.0@10.1.1.65>, Andrei Alexandrescu
<alexandrescua@mi
>cromodeling.com> writes
>>This doesn't answer to my question. You could return an auto_ptr by
>>value even if it lacked copy construction. All you had to do would
>>have been to call release() on the function return value:
>>
>>auto_ptr<Something> p1(f().release());    // ok
>
>You miss the point, exactly how is the function doing the return
going
>to manage to create a value to return, it needs a copy ctor.


Ah, now I got it: the problem is that in order to be able to return an
auto_ptr by value, f() needs access to the copy constructor, even
though it could be optimized away. Shoot!

Andrei



[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: clamage@taumet.eng.sun.com (Steve Clamage)
Date: 1999/02/28
Raw View
Francis Glassborow wrote in message ...
>I am pretty sure that does not work.  It leaves the raw pointer exposed
>during the return process which is exactly what the proponents wanted to
>avoid.  AFAIK the only way you can return by value is by calling a copy
>ctor to copy a local object to the temporary for the return.


Why wouldn't it work? You can call a method against a function return
value, couldn't you?

struct A
{
    int Method() { return 0; }
};

A f()
{
    return A();
}

int test = f().Method();

So what's the problem? It's true that the raw pointer 'flies free'
somewhere between the method call and the constructor. But the point
is that the programmer has explicitly called release(), so he/she
volunteerly agreed to get the ownership of the pointer.
Again, I don't see the local object a la auto_ptr_ref of much value
here.

>You have know idea how much time was put into trying to ensure that
>auto_ptr met the design requirements of some while not supporting to
>much dangerous behaviour.  You do not honestly think we would have
>pushed so hard against the constraints of the language for any other
>reason do you?


You ask me for a leap of faith instead of explaining me. The title of
my post reads "Something I don't understand about auto_ptr" and not
"auto_ptr sucks no matter what". I know there was a lot of effort. I'm
not proposing anything. I'm just asking why the simple and obvious
solution I hinted was considered unusable.
Let me ask my questions again. What does auto_ptr's copy and
assignment tricks exactly buy us? Why is the obvious solution of
'private'-ing them and requiring the user to call release() worse?

Andrei



[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: stephen.clamage@sun.com (Steve Clamage)
Date: 1999/02/28
Raw View

The following article appeared to have been posted by me, due to a
glitch in the script I use for posting approved articles. I
apologize for any confusion.

The article was actually posted by Andrei Alexandrescu.
---
Steve Clamage, stephen.clamage@sun.com

Francis Glassborow wrote in message ...
>I am pretty sure that does not work.  It leaves the raw pointer exposed
>during the return process which is exactly what the proponents wanted to
>avoid.  AFAIK the only way you can return by value is by calling a copy
>ctor to copy a local object to the temporary for the return.


Why wouldn't it work? You can call a method against a function return
value, couldn't you?

struct A
{
    int Method() { return 0; }
};

A f()
{
    return A();
}

int test = f().Method();

So what's the problem? It's true that the raw pointer 'flies free'
somewhere between the method call and the constructor. But the point
is that the programmer has explicitly called release(), so he/she
volunteerly agreed to get the ownership of the pointer.
Again, I don't see the local object a la auto_ptr_ref of much value
here.

>You have know idea how much time was put into trying to ensure that
>auto_ptr met the design requirements of some while not supporting to
>much dangerous behaviour.  You do not honestly think we would have
>pushed so hard against the constraints of the language for any other
>reason do you?


You ask me for a leap of faith instead of explaining me. The title of
my post reads "Something I don't understand about auto_ptr" and not
"auto_ptr sucks no matter what". I know there was a lot of effort. I'm
not proposing anything. I'm just asking why the simple and obvious
solution I hinted was considered unusable.
Let me ask my questions again. What does auto_ptr's copy and
assignment tricks exactly buy us? Why is the obvious solution of
'private'-ing them and requiring the user to call release() worse?

-Andrei


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1999/02/28
Raw View
In article <36d86c59.0@10.1.1.65>, Andrei Alexandrescu <alexandrescua@mi
cromodeling.com> writes
>This doesn't answer to my question. You could return an auto_ptr by
>value even if it lacked copy construction. All you had to do would
>have been to call release() on the function return value:
>
>auto_ptr<Something> p1(f().release());    // ok

You miss the point, exactly how is the function doing the return going
to manage to create a value to return, it needs a copy ctor.


Francis Glassborow      Chair of Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: clamage@Eng.Sun.COM (Steve Clamage)
Date: 1999/03/01
Raw View
The following article appeared to have been posted by me, due to a
glitch in the script I use for posting approved articles. I
apologize for any confusion.

The article was actually posted by Andrei Alexandrescu.
---
Steve Clamage, stephen.clamage@sun.com


Francis Glassborow wrote in message ...
>I am pretty sure that does not work.  It leaves the raw pointer exposed
>during the return process which is exactly what the proponents wanted to
>avoid.  AFAIK the only way you can return by value is by calling a copy
>ctor to copy a local object to the temporary for the return.


Why wouldn't it work? You can call a method against a function return
value, couldn't you?

struct A
{
    int Method() { return 0; }
};

A f()
{
    return A();
}

int test = f().Method();

So what's the problem? It's true that the raw pointer 'flies free'
somewhere between the method call and the constructor. But the point
is that the programmer has explicitly called release(), so he/she
volunteerly agreed to get the ownership of the pointer.
Again, I don't see the local object a la auto_ptr_ref of much value
here.

>You have know idea how much time was put into trying to ensure that
>auto_ptr met the design requirements of some while not supporting to
>much dangerous behaviour.  You do not honestly think we would have
>pushed so hard against the constraints of the language for any other
>reason do you?


You ask me for a leap of faith instead of explaining me. The title of
my post reads "Something I don't understand about auto_ptr" and not
"auto_ptr sucks no matter what". I know there was a lot of effort. I'm
not proposing anything. I'm just asking why the simple and obvious
solution I hinted was considered unusable.
Let me ask my questions again. What does auto_ptr's copy and
assignment tricks exactly buy us? Why is the obvious solution of
'private'-ing them and requiring the user to call release() worse?

Andrei


--
Steve Clamage, stephen.clamage@sun.com
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "Andrei Alexandrescu" <alexandrescua@micromodeling.com>
Date: 1999/03/01
Raw View
Dave Abrahams wrote in message
<62%B2.2392$HF4.6011057@brnws01.ne.mediaone.net>...
>That's a matter of opinion. If you always pass auto_ptr by value,
whenever
>you see one it "means" transfer of ownership, which you could argue
makes
>the code more readable. Would code be more readable if the compiler
always
>required you to explicitly write destructor calls for automatic
variables?

I disagree. Method calls are visible, while creations of temporaries
are not always. Plus: programmers are used to copy semantics, so
bearing an exception in mind for auto_ptr is not quite comfortable.
I don't see how all this links to your destructor call parallel.

Andrei
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: sbnaran@fermi.ceg.uiuc.edu (Siemel Naran)
Date: 1999/03/01
Raw View
On 28 Feb 99 08:51:27 GMT, Francis Glassborow
>In article <36d86c59.0@10.1.1.65>, Andrei Alexandrescu <alexandrescua@mi

>>This doesn't answer to my question. You could return an auto_ptr by
>>value even if it lacked copy construction. All you had to do would
>>have been to call release() on the function return value:
>>
>>auto_ptr<Something> p1(f().release());    // ok
>
>You miss the point, exactly how is the function doing the return going
>to manage to create a value to return, it needs a copy ctor.

I was about to post the same response yesterday, but then I realized
that a copy constructor is not needed.  Two examples:


1.
We normally return unnamed auto_ptr objects, as in create functions.
   std::auto_ptr<Base> read(std::istream& strm) {
      std::string s;
      strm >> s;
      typedef std::auto_ptr<Base> Result;
      if (false) ;
      else if (s=="Derived1") return Result(new Derived1());
      else if (s=="Derived2") return Result(new Derived2());
      else throw CantCreate(s);
   }
This does not require std::auto_ptr to have a copy constructor.


2.
Sometimes we return named auto_ptr objects.
   std::auto_ptr<Thing> get(std::istream& strm) {
      typedef std::auto_ptr<Thing> Result;
      Result out;
      std::string s;
      strm >> s;
      if (s=="yes") out=Result(new Thing());
      return Result(out.release()); // can't do "return out"
   }
We see that the return statement can't be written as "return out",
but instead must be written as "return Result(out.release())".


More importantly, snippet (2) can be written in the style of (1).
That is, we can eliminate the named temporary 'out'.  The resulting
code has greater locality of reference, and is therefore better:

   std::auto_ptr<Thing> get(std::istream& strm) {
      typedef std::auto_ptr<Thing> Result;
      std::string s;
      strm >> s;
      return Result(s=="yes" ? (new Thing()) : 0);
   }

--
----------------------------------
Siemel B. Naran (sbnaran@uiuc.edu)
----------------------------------
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: sbnaran@fermi.ceg.uiuc.edu (Siemel Naran)
Date: 1999/03/01
Raw View
On 28 Feb 1999 21:15:47 GMT, Steve Clamage <clamage@taumet.eng.sun.com> wrote:

                             ^^^^^^^^^^^^^
                             should be "Andrei" in this and the other post


>Ah, now I got it: the problem is that in order to be able to return an
>auto_ptr by value, f() needs access to the copy constructor, even
>though it could be optimized away. Shoot!

Even for unnamed return?

--
----------------------------------
Siemel B. Naran (sbnaran@uiuc.edu)
----------------------------------


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Biju Thomas <bijuthom@ibm.net>
Date: 1999/03/01
Raw View
Siemel Naran wrote:
>
> On 28 Feb 99 08:51:27 GMT, Francis Glassborow
> >
> >You miss the point, exactly how is the function doing the return going
> >to manage to create a value to return, it needs a copy ctor.
>
> We normally return unnamed auto_ptr objects, as in create functions.
>    std::auto_ptr<Base> read(std::istream& strm) {
>       else if (s=="Derived1") return Result(new Derived1());
[...]
>    }
> This does not require std::auto_ptr to have a copy constructor.
>

This assumes that all compilers implement the unnamed return value
optimization which is not true.

--
Best regards,
Biju Thomas
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "Andrei Alexandrescu" <alexandrescua@micromodeling.com>
Date: 1999/03/01
Raw View
Siemel Naran wrote in message ...
>>Ah, now I got it: the problem is that in order to be able to return
an
>>auto_ptr by value, f() needs access to the copy constructor, even
>>though it could be optimized away. Shoot!
>
>Even for unnamed return?


One never stops learning. You made an interesting point I didn't know
of.
I just wonder, is this standard behavior or just a peculiarity of
egcs? I'm asking that not because I don't believe you, but because you
didn't quote from the standard.

I think I'll derive something from auto_ptr, make the copy constructor
private, and give it a shot in my next non-toy project.

Andrei




[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: sbnaran@bardeen.ceg.uiuc.edu (Siemel Naran)
Date: 1999/03/01
Raw View
On 01 Mar 99 18:32:59 GMT, Biju Thomas <bijuthom@ibm.net> wrote:
>Siemel Naran wrote:

>> This does not require std::auto_ptr to have a copy constructor.

>This assumes that all compilers implement the unnamed return value
>optimization which is not true.

Indeed, you're right!  I forgot about the unnamed return value
optimization.  An accessible copy constructor is still required,
even if it is not used (ie, even if the compiler does the
return value optimization).  The following program generates an
error on egcs:

   class X
   {
      public:
         X();
      private:
         X(const X&);
   };

   X f() { return X(); } // LINE9



The error is that on LINE9, "X::X(const X&)" is private.

So disregard my earlier comments.  A copy constructor is required
for std::auto_ptr if we are to return such objects.

--
----------------------------------
Siemel B. Naran (sbnaran@uiuc.edu)
----------------------------------


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: sbnaran@bardeen.ceg.uiuc.edu (Siemel Naran)
Date: 1999/03/02
Raw View
On 1 Mar 1999 21:33:49 GMT, Andrei Alexandrescu

>One never stops learning. You made an interesting point I didn't know of.
>I just wonder, is this standard behavior or just a peculiarity of
>egcs? I'm asking that not because I don't believe you, but because you
>didn't quote from the standard.

The standard talks of the named and unnamed return value optimization.
This means that there is such a thing as the named and unnamed return
value un-optimization.  (IOW, if compiler had to do the return value
optimization for unnamed objects, then why mention the concept of
unnamed return value optimization?)
In the return value un-optimization,
   { return T(); }
invokes a call to the copy constructor upon return.


>I think I'll derive something from auto_ptr, make the copy constructor
>private, and give it a shot in my next non-toy project.

Better to not use inheritance.
Just make a myspace::auto_ptr.
There is now no conversion from myspace::auto_ptr to std::auto_ptr.

--
----------------------------------
Siemel B. Naran (sbnaran@uiuc.edu)
----------------------------------
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Gabriel Dos_Reis <gdosreis@sophia.inria.fr>
Date: 1999/03/02
Raw View
sbnaran@fermi.ceg.uiuc.edu (Siemel Naran) writes:

[...]

=B7-------------
| Even for unnamed return?
=B7-------------

Yes, even for unnamed retunr value. See 12.8/14


"Andrei Alexandrescu" <alexandrescua@micromodeling.com> writes:

=B7-------------
| One never stops learning. You made an interesting point I didn't know
| of.
| I just wonder, is this standard behavior or just a peculiarity of
| egcs? I'm asking that not because I don't believe you, but because you
| didn't quote from the standard.
|=20
| I think I'll derive something from auto_ptr, make the copy constructor
| private, and give it a shot in my next non-toy project.
=B7-------------

Optimizations are performed under the "as-if" rule. That means even=20
if the copy-ctor call is optimized away---regardless of whether the
return value is named or not---the semantics restrictions must apply.=20

--=20
Gabriel Dos Reis, dosreis@cmla.ens-cachan.fr
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "Andrei Alexandrescu" <alexandrescua@micromodeling.com>
Date: 1999/03/02
Raw View
Biju Thomas wrote in message <36DA9DCF.2EF7A26D@ibm.net>...
>Siemel Naran wrote:
>>
>> On 28 Feb 99 08:51:27 GMT, Francis Glassborow
>> >
>> >You miss the point, exactly how is the function doing the return
going
>> >to manage to create a value to return, it needs a copy ctor.
>>
>> We normally return unnamed auto_ptr objects, as in create
functions.
>>    std::auto_ptr<Base> read(std::istream& strm) {
>>       else if (s=="Derived1") return Result(new Derived1());
>[...]
>>    }
>> This does not require std::auto_ptr to have a copy constructor.
>>
>
>This assumes that all compilers implement the unnamed return value
>optimization which is not true.

I think optimization has nothing to do in here. Prior to apply any
optimization, the compiler checks for access. For instance, let's try
this:

class A
{
    A(const A &);
public:
    A(int) {}
};

A Var1(5);
A Var2 = 5;

Say we have a compiler that fully supports RVO.
In the presence of RVO, the two definitions above should be
equivalent. However, the compiler will first check for access to the
copy constructor, even if it doesn't call it at all! So the code above
will generate a compile-time error on the most optimizing compiler.

You can actually test whether a compiler implements RVO by declaring
the copy constructor public but not defining it. If you have a linker
error, the compiler generated a call to the copy constructor.

So I think Siemel's point is valid.

Andrei
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]