473,399 Members | 2,278 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,399 software developers and data experts.

scope and references to temporaries

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
7 1674
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
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
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
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
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
> 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
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 thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

17
by: Tom | last post by:
The motivation for references seems clear: stop people from using nasty pointers when all they really want is a reference to an object. But C++ references are so inadequate that I'm still using...
2
by: Jeremy J | last post by:
Hello, I recall reading an interesting article on automatic scope guard by A. Alexandrescu on CUJ.com some time ago. I have since integrated my code into my project and I find it to be very...
3
by: Grant Wagner | last post by:
Given the following working code: function attributes() { var attr1 = arguments || '_'; var attr2 = arguments || '_'; return ( function (el1, el2) { var value1 = el1 + el1; var value2 = el2...
10
by: ATASLO | last post by:
In the following example, section #3 fails under VC98, VC2003, VC2005 Express Beta (Aug 2004) and g++ 3.3.2. Is this just a pitfall of the C++ specification? Why don't any of the above compilers...
6
by: Neelesh Bodas | last post by:
Hello All, I was just listing down various ways in which variables can be created and destroyed in C++. (On the lines of 10.4.3 TC++PL Ed 3) Putting the summary here for corrections, comments,...
14
by: gerald.dalley | last post by:
I've been trying to pin down the scoping rules for temporary variables in C++. I know that doing something like: string s("abc"); const char *t = (s+"def").c_str(); cout << t; is invalid...
28
by: Frederick Gotham | last post by:
When I was a beginner in C++, I struggled with the idea of references. Having learned how to use pointers first, I was hesitant to accept that references just "do their job" and that's it. Just...
11
by: =?iso-8859-1?q?Erik_Wikstr=F6m?= | last post by:
struct foo { int i; }; int bar(foo& f) { return f.i++; } int main() { bar(foo());
7
by: Johannes Bauer | last post by:
Hello Group, please consider the following code #include <vector> #include <iostream> #define USE_CONST #define USE_STRING
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.