Topic: Question about temporaries


Author: feathers@serss0 (Michael Feathers)
Date: Sun, 24 Jan 1993 23:38:35 GMT
Raw View
Has the ANSI committee done any more work of the lifetime of temporaries?
I'm very curious about this aspect of the emerging standard.







Author: pkt@lpi.liant.com (Scott Turner)
Date: Mon, 25 Jan 1993 16:31:50 GMT
Raw View
In article <C1DtoB.FJ3@fiu.edu>, feathers@serss0 (Michael Feathers) writes:
>
> Has the ANSI committee done any more work of the lifetime of temporaries?
> I'm very curious about this aspect of the emerging standard.

At the Boston meeting last November, some straw votes were taken to get
the sense of the committee of the whole.  IMO there was a clear leader
among the possibilities which seemed viable at the time.  Unfortunately
no prize was awarded. :-)  38 voted that the following was acceptable,
and none voted that it was unacceptable.

     Temporaries are normally destroyed at the end of the statement
     in which they are created.  The exception is that temporaries
     created within a branch of a conditional (?:) operator are destroyed
     when that branch is completed (and analogously for && and ||).

I would say that the committee was ready to compromise and decide on this
except for one thing.  Nearly all of the discussion has assumed that we
know what is a "temporary".  When asked directly regarding the formal
argument x in the function
     class C { ...  C (const C&);  ... };
     void f(class C x) {   ... use x ...   }
most people would say x is _not_ a temporary.  On the other hand, a very
popular implementation of C++ gives x the same extended lifetime as a
temporary.  Also, more than one example presented in favor of long-lived
temporaries has actually needed long-lived formal arguments!  If I recall
correctly, an example was
     String x, y;
     char *z;
     extern char *f(String);
     z = f(x+y);
--
Prescott K. Turner, Jr.
Liant Software Corp. (developers of LPI languages)
959 Concord St., Framingham, MA 01701 USA    (508) 872-8700
UUCP: uunet!lpi!pkt                          Internet: pkt@lpi.liant.com




Author: steve@taumet.com (Steve Clamage)
Date: Mon, 25 Jan 1993 18:22:32 GMT
Raw View
feathers@serss0 (Michael Feathers) writes:


>Has the ANSI committee done any more work of the lifetime of temporaries?
>I'm very curious about this aspect of the emerging standard.

It is still under discussion and has not yet been resolved.  I expect
that it will be resolved this year.

It is a hard problem, with excellent arguments both in favor of and
against all solutions proposed so far.

Once it has been resolved, it may take a while for existing
implementations to catch up to any needed changes.  So the best
advice so far is still to avoid dependencies in your code on how
long a temporary will live.
--

Steve Clamage, TauMetric Corp, steve@taumet.com




Author: jbuck@forney.berkeley.edu (Joe Buck)
Date: 27 Jan 1993 20:11:19 GMT
Raw View
In article <1993Jan25.163150.24449@lpi.liant.com> pkt@lpi.liant.com (Scott Turner) writes:
> [proposed rule on lifetime of temporaries]
>     Temporaries are normally destroyed at the end of the statement
>     in which they are created.  The exception is that temporaries
>     created within a branch of a conditional (?:) operator are destroyed
>     when that branch is completed (and analogously for && and ||).

This seems like the most reasonable compromise.

>I would say that the committee was ready to compromise and decide on this
>except for one thing.  Nearly all of the discussion has assumed that we
>know what is a "temporary".  When asked directly regarding the formal
>argument x in the function

 class C { ...  C (const C&);  ... };
 void f(class C x) {   ... use x ...   }

>most people would say x is _not_ a temporary.

This is true, but that has nothing to do with your example below.  The
formal parameter x is a different thing entirely from the actual
parameter that is assigned to it.  The latter may be a temporary but
the former is not.

I changed the variable from x to w in your example to avoid confusion
(two different x's).

     String w, y;
     char *z;
     extern char *f(String x);
     z = f(w+y);

In this example there is a temporary that is the result of w+y.  This
temporary gets assigned to the formal parameter x of function f by means
of the copy constructor, at least conceptually.  But it could still be
considered a temporary in the sense of the rule above, meaning that it
lives until the semicolon.  Under this interpretation, we would have the
following action: temporary t is set to the result of w+y; this temporary
is passed to the x parameter of f with the copy constructor; at the end
of f that copy is destroyed, but t is still alive; the result is assigned
to z, and then t is destroyed.

The result is the same as if we replace the final statement above with

 { String& t = w+y; z = f(t);}

Note that this has a cost: we cannot eliminate the copy constructor and
initialize x "in place" anymore.  This means that the fundamental cost
of passing an object by value has increased.


--
Joe Buck jbuck@ohm.berkeley.edu




Author: jimad@microsoft.com (Jim Adcock)
Date: 30 Jan 93 19:04:31 GMT
Raw View
In article <1993Jan25.163150.24449@lpi.liant.com> pkt@lpi.liant.com (Scott Turner) writes:
|I would say that the committee was ready to compromise and decide on this
|except for one thing.  Nearly all of the discussion has assumed that we
|know what is a "temporary".

Okay, so what _is_ a "temporary" ????

Here's my strawman proposal:

A temporary is any object _not_ meeting any of the following criteria:

* has a name.
* is an element of a non-temporary.
* is a member of a non-temporary.
* is created on the heap [via a new].

=====

The rationale is as follows:

*if an object has a name the object's lifetime is that of the scope of its
name and thus cannot be the lifetime of a temporary and thus cannot be
a temporary.

*if an object is an element the object's lifetime is that of the lifetime
of the non-temporary array of which it is an element and thus cannot be
the lifetime of a temporary and thus cannot be a temporary.

*if an object is an member the object's lifetime is that of the lifetime
of the non-temporary object of which it is a member and thus cannot be
the lifetime of a temporary and thus cannot be a temporary.

*if the object is created on the heap then the object exists until deleted
and thus cannot be the lifetime of a temporary and thus cannot be a temporary.

=====

Note:

a reference gives an object a name and therefor its referenced object
is not a temporary.

a pointer does not give an object a name and therefor the pointed-at
object could very-well be a temporary which may be destroyed before
you get around to trying to access it via that pointer.





Author: dag@bellman.control.lth.se (Dag Bruck)
Date: Mon, 1 Feb 1993 07:19:10 GMT
Raw View
There has been a lot of discussion about when temporaries are
destroyed.  As far as I can tell, there is nothing that describes when
a temporary may be created.

Imagine a real-time application, and that I have some code protected
by a semaphore.  I would not want the code optimizer to hoist the
creation of the temporary outside the protected region.

I know this may not be an area that the C++ standard should address,
but I'm certain C++ will be used in applications where it matters.

If someone could help me find a useful definition of "reentrant", I
would like to suggest that the standard C++ library should be
reentrant, except for functions explicitly listed by the vendor.  Note
that a vendor is not _required_ to make the library reentrant, but the
user has a fighting chance to know what functions may be used.  You
can imagine my suprise when I found out that fabs() was not reentrant
in an old version of Microsoft C!  (I don't know the current status.)


    -- Dag




Author: pkt@lpi.liant.com (Scott Turner)
Date: Mon, 1 Feb 1993 15:18:16 GMT
Raw View
In article <1k6q97$c33@agate.berkeley.edu>, jbuck@forney.berkeley.edu (Joe Buck) writes:
> In article <1993Jan25.163150.24449@lpi.liant.com> pkt@lpi.liant.com (Scott Turner) writes:
> >Nearly all of the discussion has assumed that we
> >know what is a "temporary".  When asked directly regarding the formal
> >argument x in the function
>
>  class C { ...  C (const C&);  ... };
>  void f(class C x) {   ... use x ...   }
>
> >most people would say x is _not_ a temporary.
>
> This is true, but that has nothing to do with your example below.  The
> formal parameter x is a different thing entirely from the actual
> parameter that is assigned to it.  The latter may be a temporary but
> the former is not.

Correct.  I should have been more precise in what I said.  (And you
shouldn't talk of the temporary being "assigned" to the formal parameter;
it initializes the formal.)  My point stands, and I'll reiterate it.

A very popular implementation of C++ gives x a lifetime which extends as
long as that of a temporary created in the context where f is called.
Also, more than one example presented in favor of long-lived temporaries
has actually needed long-lived formal arguments!  By this I mean formal
arguments whose destruction is delayed _beyond_ the time when the function
returns.  If I recall correctly, an example was
     String w, y;
     char *z;
     extern char *foo(String);
     z = foo(w+y);
The function foo returns a pointer dependent on the lifetime of foo's
formal parameter.  This "works" in some popular implementations, because
the formal parameter of foo is not destroyed until the end of the block
in which the call to foo appears.  So in those implementations the pointer
assigned to z remains valid until the end of the block.

At one point in the C++ standards committee's discussions an example like
this one was important.  Should it be important in the future?
--
Prescott K. Turner, Jr.
Liant Software Corp. (developers of LPI languages)
959 Concord St., Framingham, MA 01701 USA    (508) 872-8700
UUCP: uunet!lpi!pkt                          Internet: pkt@lpi.liant.com