By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
457,923 Members | 1,330 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 457,923 IT Pros & Developers. It's quick & easy.

scope and references to temporaries

P: n/a
REH
Though unsafe, is this legal:

const int& foo(const int& i)
{
return i;
}

int j = foo(5);

does the temporary live long enough to be assigned to j?

REH
Apr 30 '06 #1
Share this Question
Share on Google+
7 Replies


P: n/a
REH wrote:
Though unsafe, is this legal:

const int& foo(const int& i)
{
return i;
}

int j = foo(5);

does the temporary live long enough to be assigned to j?


No. It lives only as long as 'i' inside the 'foo' function scope. As
soon as you return from 'foo', the reference bound to the temporary
goes out of scope, its lifetime ends, and so the temporary itself is
destroyed. The return value reference (initialised from 'i', which is
valid at *that* point) becomes invalid. Trying to initialise 'j' with
it is a crap shoot (undefined behaviour).

So, it's syntactically legal, produces undefined behaviour, and as to
"illegal", I do think it is only illegal in those countries where UB
is outlawed.

V
--
Please remove capital As from my address when replying by mail
Apr 30 '06 #2

P: n/a
REH

"Victor Bazarov" <v.********@comAcast.net> wrote in message
news:5f********************@comcast.com...
REH wrote:
Though unsafe, is this legal:

const int& foo(const int& i)
{
return i;
}

int j = foo(5);

does the temporary live long enough to be assigned to j?


No. It lives only as long as 'i' inside the 'foo' function scope. As
soon as you return from 'foo', the reference bound to the temporary
goes out of scope, its lifetime ends, and so the temporary itself is
destroyed. The return value reference (initialised from 'i', which is
valid at *that* point) becomes invalid. Trying to initialise 'j' with
it is a crap shoot (undefined behaviour).

So, it's syntactically legal, produces undefined behaviour, and as to
"illegal", I do think it is only illegal in those countries where UB
is outlawed.


Thanks Victor.

REH
Apr 30 '06 #3

P: n/a
Victor Bazarov wrote:
REH wrote:
const int& foo(const int& i)
{
return i;
}

int j = foo(5);

does the temporary live long enough to be assigned to j?


No. It lives only as long as 'i' inside the 'foo' function scope. As
soon as you return from 'foo', the reference bound to the temporary
goes out of scope, its lifetime ends, and so the temporary itself is
destroyed. The return value reference (initialised from 'i', which is
valid at *that* point) becomes invalid. Trying to initialise 'j' with
it is a crap shoot (undefined behaviour).


Is that so?

[12.2/5]
[...] A temporary bound to a reference parameter in a function call
(5.2.2) persists until the completion of the full expression containing
the call. [...]

If I read the Standard correctly, the above code doesn't produce a "crap
shoot". Am I missing something?

--
Martin
Apr 30 '06 #4

P: n/a
Martin Vejnár wrote:
Victor Bazarov wrote:
REH wrote:
const int& foo(const int& i)
{
return i;
}

int j = foo(5);

does the temporary live long enough to be assigned to j?


No. It lives only as long as 'i' inside the 'foo' function scope. As
soon as you return from 'foo', the reference bound to the
temporary goes out of scope, its lifetime ends, and so the temporary
itself is destroyed. The return value reference (initialised from
'i', which is valid at *that* point) becomes invalid. Trying to
initialise 'j' with it is a crap shoot (undefined behaviour).


Is that so?

[12.2/5]
[...] A temporary bound to a reference parameter in a function
call (5.2.2) persists until the completion of the full expression
containing the call. [...]

If I read the Standard correctly, the above code doesn't produce a
"crap shoot". Am I missing something?


You're right, I must have missed that particular part of this valuable
paragraph. Thank you for the correction.

V
--
Please remove capital As from my address when replying by mail
Apr 30 '06 #5

P: n/a
On Sun, 30 Apr 2006 16:10:46 GMT, "REH" <me@you.com> wrote:
Though unsafe, is this legal:

const int& foo(const int& i)
{
return i;
}

int j = foo(5);

Yes.
does the temporary live long enough to be assigned to j?

REH


The standard says that the temporary should live long enough for the
expression enclosing it to finish, but I wouldn't necessarily count on
this behavior unless you are sure that your particular compiler gets
it right.

--
Bob Hairgrove
No**********@Home.com
May 1 '06 #6

P: n/a
> The standard says that the temporary should live long enough for the
expression enclosing it to finish, but I wouldn't necessarily count on
this behavior unless you are sure that your particular compiler gets
it right.


Okay. Here is another example:

template <class First, class Second>
class Plus
{
public:
Plus( const First & first, const Second & second ) : first( first ),
second( second ) { }
template <class Third>
Plus< Plus<First, Second>, Third > operator+( const Third & third ) { return
Plus<Plus<First,Second>, Third>( *this, third ); }
const First & first;
const Second & second;
};

class Matrix
{
public:
Plus<Matrix, Matrix> operator+( const Matrix & m ) const { return
Plus<Matrix, Matrix>( *this, m ); }
template <class Type>
Matrix & operator=( const Type & type ) { /* whatever */ return *this; }
};

void test()
{
Matrix a, b, c, d;
a = b + c + d; // [1]
}

Will the temporaries created at [1] live until the whole expression is
finished (ie. until the assignment to 'a' completes)? As far as I know, the
code should be legal since all temporaries created during an evaluation of
an expression (statement) must live until the end of the statement. In fact,
all expression templates based linear algebra labraries rely on this
behaviour.

Thanks
-- Marek
May 1 '06 #7

P: n/a
Bob Hairgrove wrote:

The standard says that the temporary should live long enough for the
expression enclosing it to finish, but I wouldn't necessarily count on
this behavior unless you are sure that your particular compiler gets
it right.


If you're compiler doesn't get this right, it should be discarded.
This is a fairly fundamental concept to the language.
May 1 '06 #8

This discussion thread is closed

Replies have been disabled for this discussion.