Topic: Destruction order of temporary
Author: haberg@REMOVE.matematik.su.se (Hans Aberg)
Date: 1998/08/07 Raw View
In article <35CA1D83.6BA5@noSPAM.central.beasys.com>,
dtribble@technologist.com wrote:
>> Here's one case that I believe _must_ break stack order:
>>
>> foo x(bar());
...
>It's conceivable that:
> 1. the foo object 'x' is allocated by ::new() (or foo::new()),
> 2. the bar temporary object is allocated by ::new() (or bar::new()),
> 3. the temporary is constructed by bar::bar(),
> 4. the temporary is passed to foo::foo(bar&), which constructs 'x',
> 5. the temporary is destructed by bar::~bar(),
> 6. the temporary is deallocated by ::delete().
What is "::new()" here? I know of "::operator new" (for memory
allocation alone), and "new T()" used to memory allocate and construct an
object.
I do not think that temporaries use "::operator new" at all if it can be
avoided, as it is slow: Instead registers are used whenever possible.
Hans Aberg * Anti-spam: Remove "REMOVE." from email address.
* Email: Hans Aberg <haberg@REMOVE.member.ams.org>
* Home Page: <http://www.matematik.su.se/~haberg/>
* AMS member listing: <http://www.ams.org/cml/>
[ 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: AllanW@my-dejanews.com
Date: 1998/08/07 Raw View
Are you suggesting that a compiler might create temporary objects in
the heap, rather than on the stack (or wherever else auto objects are
created)?
> But I doubt that many compilers would actually do it this way.
> OTOH, this could be some kind of optimization that provides some
> benefit for certain compilers.
Perhaps a machine that doesn't have a stack -- but it seems to me
that such a machine already has to simulate one in the C runtime
(in order to support recursion).
Or, perhaps a machine that does use a stack, but the size is very
limited -- so the compiler stores declared auto variables on the
stack and temporaries in the heap.
...But that's stretching things, isn't it?
The usual assumption is that the stack is much quicker than even
the best heap implementation, because there's no memory management
as such (no free list, no combining blocks, etc.) So an implementation
matching your description would be suboptimal, no?
--
AllanW@my-dejanews.com is a "Spam Magnet" -- never read.
Please reply in USENET only, sorry.
-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/rg_mkgrp.xp Create Your Own Free Member Forum
[ 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: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 1998/08/06 Raw View
Hans Aberg wrote:
>
> In article <6q7p8q$n0l$1@nnrp1.dejanews.com>, AllanW@my-dejanews.com wrote:
> >You seem to think that the last sentance
> > This applies to both explicitly declared objects and temporaries.
> >implies an order -- first explicitly declared objects, then temporaries.
> >But there is nothing there to say what order it's done in.
>
> All I want to know if the objects, relative to each other, are destroyed
> in the reverse order they were constructed. I have not implied any "first
> declared and temporaries" order in this, which otherwise is irrelevant for
> my question.
>
> What I think happens is that the temporaries are simply flipped into
> registers and destroyed as soon as they can when they have been used to
> make room for new temproraries in the registers, because it is fast. This
> destroys the stack order, then.
>
> But if it does not happen (that is, the stack order is preserved also
> when the temporaries are mixed into the picture), it would be a miracle
> that can be used in GC implementation. But then would want to hear from
> somebody who can swear by it.
There are some ways to change the order of destruction of temporaries.
For example, the following code:
{ Foo const& fooref = Foo(Bar()); ; }
First, a temporary Bar is constructed, which is then used to construct
a temporary Foo, which is bound to a reference, thus extending the
lifetime until the end of the scope (which is the end of the reference
lifetime as well). Then, at the end of the expression, the temporary
Bar is destructed, while the temporary Foo still exists and is then
destroyed at the end of the scope. Therefore the order of calls is
Bar::Bar()
Foo::Foo(Bar const&)
Bar::~Bar()
Foo::~Foo()
However, the order of destruction is specified, therefore your
"destroy as soon as you can"-Rule can only be followed if it
doesn't change the program behaviour (esp. the order is fixed if
the destructors have observable behaviour).
[ 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: David R Tribble <david.tribble@noSPAM.central.beasys.com>
Date: 1998/08/06 Raw View
Hans Aberg wrote:
>> So this older version admits that temporaries are destroyed earlier,
>> thus breaking the stack order, and I also know that this is the case
>> with my (older) C++ compiler, because I wrote a program and checked
>> it.
Paul D. DeRocco wrote:
> Here's one case that I believe _must_ break stack order:
>
> foo x(bar());
>
> Assuming that both foos and bars are class types with constructors and
> destructors, this would create a temporary bar, use it as a parameter
> when constructing a foo, and then destroy the bar. How could it do
> otherwise?
It's conceivable that:
1. the foo object 'x' is allocated by ::new() (or foo::new()),
2. the bar temporary object is allocated by ::new() (or bar::new()),
3. the temporary is constructed by bar::bar(),
4. the temporary is passed to foo::foo(bar&), which constructs 'x',
5. the temporary is destructed by bar::~bar(),
6. the temporary is deallocated by ::delete().
After all, the declarator for 'x' precedes that of the bar temporary
(or does it actually end at the closing ')'?).
But I doubt that many compilers would actually do it this way.
OTOH, this could be some kind of optimization that provides some
benefit for certain compilers.
-- David R. Tribble, dtribble@technologist.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: AllanW@my-dejanews.com
Date: 1998/08/04 Raw View
In article <haberg-0408981306260001@sl94.modempool.kth.se>,
haberg@REMOVE.matematik.su.se (Hans Aberg) wrote:
[Snippity do dah]
> So, CD2, "Jump statements", section 6.6, the second paragraph says:
>
> On exit from a scope (however accomplished), destructors
> (_class.dtor_) are called for all constructed objects with automatic
> storage duration (_basic.stc.auto_) (named objects or temporaries)
> that are declared in that scope, in the reverse order of their decla-
> ration.
>
> So this sounds as if the stack order is guaranteed to be preserved. But in
> the older ARM 1994, the same paragraph reads:
>
> On exit from a scope (however accomplished) destructors are called for all
> constructed class objects in that scope that have not yet been destroyed.
> This applies to both explicitly declared objects and temporaries.
>
> So this older version admits that temporaries are destroyed earlier, thus
> breaking the stack order, and I also know that this is the case with my
> (older) C++ compiler, because I wrote a program and checked it.
I think you are reading this wrong. To me, the two paragraphs are almost
identical. The first one adds "in the reverse order of their declaration"
but otherwise there is no important difference.
You seem to think that the last sentance
This applies to both explicitly declared objects and temporaries.
implies an order -- first explicitly declared objects, then temporaries.
But there is nothing there to say what order it's done in.
(I think there was something else that stated that destruction was always
in reverse order of construction, but I'm no longer certain.)
-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/rg_mkgrp.xp Create Your Own Free Member Forum
[ 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: haberg@REMOVE.matematik.su.se (Hans Aberg)
Date: 1998/08/05 Raw View
In article <6q7p8q$n0l$1@nnrp1.dejanews.com>, AllanW@my-dejanews.com wrote:
>You seem to think that the last sentance
> This applies to both explicitly declared objects and temporaries.
>implies an order -- first explicitly declared objects, then temporaries.
>But there is nothing there to say what order it's done in.
All I want to know if the objects, relative to each other, are destroyed
in the reverse order they were constructed. I have not implied any "first
declared and temporaries" order in this, which otherwise is irrelevant for
my question.
What I think happens is that the temporaries are simply flipped into
registers and destroyed as soon as they can when they have been used to
make room for new temproraries in the registers, because it is fast. This
destroys the stack order, then.
But if it does not happen (that is, the stack order is preserved also
when the temporaries are mixed into the picture), it would be a miracle
that can be used in GC implementation. But then would want to hear from
somebody who can swear by it.
Hans Aberg * Anti-spam: Remove "REMOVE." from email address.
* Email: Hans Aberg <mailto:haberg@member.ams.org>
* Home Page: <http://www.matematik.su.se/~haberg/>
* AMS member listing: <http://www.ams.org/cml/>
[ 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: "Paul D. DeRocco" <pderocco@ix.netcom.com>
Date: 1998/08/05 Raw View
Hans Aberg wrote:
>
> So this older version admits that temporaries are destroyed earlier,
> thus breaking the stack order, and I also know that this is the case
> with my (older) C++ compiler, because I wrote a program and checked
> it.
Here's one case that I believe _must_ break stack order:
foo x(bar());
Assuming that both foos and bars are class types with constructors and
destructors, this would create a temporary bar, use it as a parameter
when constructing a foo, and then destroy the bar. How could it do
otherwise?
--
Ciao,
Paul
[ 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: "Bill Wade" <bill.wade@stoner.com>
Date: 1998/08/05 Raw View
Hans Aberg wrote in message ...
> [ Do auto's get destroyed in reverse order of construction ]
A few trivial counter-examples you probably don't care about:
1) One auto may be destroyed before another auto is constructed, they
obviously won't be destroyed in reverse order.
2) Some auto's may not get destroyed (see exit()).
3) Explicit destruction and placement new can throw in extra
constructions/destructions of auto objects.
More serious:
I think the return value optimization can make later-constructed objects be
destroyed later.
class Foo { ... };
Foo MakeFoo(){ Foo f, g; return g; }
void Bar()
{
Foo x(MakeFoo());
}
I believe it is possible (return value optimization) that 'g' is an alias
for 'x'. 'g' is constructed after 'f', but if 'g' is an alias for 'x' it
will also be destructed after 'f'.
Note that destruction remains in reverse stack order, however construction
was not in stack order.
Cheers.
[ 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: haberg@REMOVE.matematik.su.se (Hans Aberg)
Date: 1998/08/04 Raw View
(This question came up in the thread "Dynamic cast of virtual function
pointers", but I post it here to make it more visible to those not
following that thread.)
The question is whether there has been a change the standard of C++, so
that automatic objects, declared and temporary, taken together are always
destroyed in the reverse order they are created.
The context is this: If one wants to keep track of the root set in a GC
(garbage collector), then one may simply use the constructors of the
relevant automatic objects to stack their "this" pointers, and use their
destructors to simple pop the stack. If the destruction order between
different automatic objects is always to be known to be the reverse of
their relative creation order, then this stack order is preserved, and the
stack will always contain the relevant root set.
But if this order is not preserved, then the program will bomb.
So, CD2, "Jump statements", section 6.6, the second paragraph says:
On exit from a scope (however accomplished), destructors
(_class.dtor_) are called for all constructed objects with automatic
storage duration (_basic.stc.auto_) (named objects or temporaries)
that are declared in that scope, in the reverse order of their decla-
ration.
So this sounds as if the stack order is guaranteed to be preserved. But in
the older ARM 1994, the same paragraph reads:
On exit from a scope (however accomplished) destructors are called for all
constructed class objects in that scope that have not yet been destroyed.
This applies to both explicitly declared objects and temporaries.
So this older version admits that temporaries are destroyed earlier, thus
breaking the stack order, and I also know that this is the case with my
(older) C++ compiler, because I wrote a program and checked it.
So what is the story? Has the C++ standard changed so that one is
guaranteed that the stack order of the automatic objects is never broken?
I want to hear from somebody who really, really _knows_, so if I make
use of this feature, I can be absolutely sure that my program does not
bomb (if I get hold of a conforming compiler, that is).
Hans Aberg * Anti-spam: Remove "REMOVE." from email address.
* Email: Hans Aberg <mailto:haberg@member.ams.org>
* Home Page: <http://www.matematik.su.se/~haberg/>
* AMS member listing: <http://www.ams.org/cml/>
---
[ 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 ]