Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

"lifetime of temporary bound to reference..."

1 view
Skip to first unread message

Igor R.

unread,
Jan 26, 2009, 1:19:17 PM1/26/09
to
Hello,

Does the rule in the subj applies to the following:

std::pair<int, int> getPair()
{
return std::pair<int, int>(1, 2);
}

int main()
{
// is this legal?
const std::pair<int, int> &p1 = getPair();
// and this?
std::pair<int, int> &p2 = getPair();
std::cout << p1.first << p2.second;
}

Victor Bazarov

unread,
Jan 26, 2009, 1:25:10 PM1/26/09
to
Igor R. wrote:
> Does the rule in the subj applies to the following:
>
> std::pair<int, int> getPair()
> {
> return std::pair<int, int>(1, 2);
> }
>
> int main()
> {
> // is this legal?
> const std::pair<int, int> &p1 = getPair();

Yes, this is legal. The temporary returned by 'getPair' will have the
same lifetime as the 'p1' reference (i.e. until 'main' returns).

> // and this?
> std::pair<int, int> &p2 = getPair();

No, this is not legal. A temporary can only be bound to a reference to
const.

> std::cout << p1.first << p2.second;
> }

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask

James Kanze

unread,
Jan 27, 2009, 3:53:00 AM1/27/09
to
On Jan 26, 7:25 pm, Victor Bazarov <v.Abaza...@comAcast.net> wrote:
> Igor R. wrote:
> > Does the rule in the subj applies to the following:

First, very importantly, the rule in the subject doesn't exist.
Whether a temporary is bound to a reference has no effect on its
lifetime. The only time the lifetime of a temporary is extended
is if a reference is initialized with a rvalue. (The
difference, of course, is whether a temporary is bound to a
reference is a transitive relationship; whether a temporary was
initialized with an rvalue isn't.)

> > std::pair<int, int> getPair()
> > {
> > return std::pair<int, int>(1, 2);
> > }

> > int main()
> > {
> > // is this legal?
> > const std::pair<int, int> &p1 = getPair();

> Yes, this is legal. The temporary returned by 'getPair' will
> have the same lifetime as the 'p1' reference (i.e. until
> 'main' returns).

Formally, it might be a copy of the temporary (which is also a
temporary) which has its lifetime extended (but I think this
possibility will be removed from C++0x).

> > // and this?
> > std::pair<int, int> &p2 = getPair();

> No, this is not legal. A temporary can only be bound to a
> reference to const.

No! A reference can only be initialized with an rvalue if it is
const and non volatile. But it's quite possible to arrange for
a temporary to bind to a non-const reference (const_cast, member
functions, etc.).

This point is in some ways related to my initial comment, above:
in order to bind a temporary to a non-const reference, you must
somehow arrange for the expression to be an lvalue. And since
the initialization expression of the temporary is not an rvalue,
the lifetime of the temporary will NOT be extended.

This is probably best explained with a simple example:

struct S
{
S& me() { return *this ; }
} ;

S& rs = S().me() ;

The reference rs is clearly bound to a temporary, even though
the reference is non-const. On the other hand, the reference
was not initialized with an rvalue expression, so the lifetime
of the temporary will NOT be extended beyond the end of the full
expression. (Technically, the temporary object S() will be
destructed before the reference rs is initialized. In practice,
there's no way a conforming program can tell, however.)

--
James Kanze (GABI Software) email:james...@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Victor Bazarov

unread,
Jan 27, 2009, 8:49:05 AM1/27/09
to
James Kanze wrote:
> On Jan 26, 7:25 pm, Victor Bazarov <v.Abaza...@comAcast.net> wrote:
>> Igor R. wrote:
>>> Does the rule in the subj applies to the following:
>
> First, very importantly, the rule in the subject doesn't exist.
> Whether a temporary is bound to a reference has no effect on its
> lifetime. The only time the lifetime of a temporary is extended
> is if a reference is initialized with a rvalue. (The
> difference, of course, is whether a temporary is bound to a
> reference is a transitive relationship; whether a temporary was
> initialized with an rvalue isn't.)

I believe you're attempting to split hairs. Please see the second
sentence of 12.2/5. "The temporary to which the reference is bound ...
persists for the lifetime of the reference". If that's not "lifetime of
temporary bound to reference", what exactly is it?

> [..]


>
> struct S
> {
> S& me() { return *this ; }
> } ;
>
> S& rs = S().me() ;
>
> The reference rs is clearly bound to a temporary, even though
> the reference is non-const. On the other hand, the reference
> was not initialized with an rvalue expression, so the lifetime
> of the temporary will NOT be extended beyond the end of the full
> expression. (Technically, the temporary object S() will be
> destructed before the reference rs is initialized. In practice,
> there's no way a conforming program can tell, however.)
>

A conforming program? If the temporary is destructed before 'rs' is
initialised, doesn't this program have undefined behavior? Is it
conforming regardless of having UB?

Don't bother. The two identical halves of the hair split by this
perfect exercise have fallen gracefully to the floor. Success! The OP
now knows that he wouldn't be able to tell one half from the other in a
conforming program. Heaps of knowledge.

I honestly regret wasting time reading your reply.

James Kanze

unread,
Jan 28, 2009, 4:40:34 AM1/28/09
to
On Jan 27, 2:49 pm, Victor Bazarov <v.Abaza...@comAcast.net> wrote:
> James Kanze wrote:
> > On Jan 26, 7:25 pm, Victor Bazarov <v.Abaza...@comAcast.net> wrote:
> >> Igor R. wrote:
> >>> Does the rule in the subj applies to the following:

> > First, very importantly, the rule in the subject doesn't
> > exist. Whether a temporary is bound to a reference has no
> > effect on its lifetime. The only time the lifetime of a
> > temporary is extended is if a reference is initialized with
> > a rvalue. (The difference, of course, is whether a
> > temporary is bound to a reference is a transitive
> > relationship; whether a temporary was initialized with an
> > rvalue isn't.)

> I believe you're attempting to split hairs. Please see the
> second sentence of 12.2/5. "The temporary to which the
> reference is bound ... persists for the lifetime of the
> reference". If that's not "lifetime of temporary bound to
> reference", what exactly is it?

That's an interesting quote, because of course, it's neither
implementable, nor implemented.

My point wasn't meant to split hairs. It was to point out a
very important distinction: the fact that the extension of
lifetime is not transitive. The lifetime is only extended to
match that of the reference which was initialized with the
expression generating the temporary. The fact that some
reference is bound to a temporary doesn't guarantee that that
temporary will not be destroyed while the reference is still
usable.

0 new messages