473,326 Members | 2,175 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,326 software developers and data experts.

Object lifetimes when bound to references

Hello,

during a discussion on a C++ internet forum, some question came up
regarding references and the lifetime of the objects they alias.

I can't find any clear wording on that in the draft standard. Example
12.2 in the standard document illustrates that temporaries bound to
references-to-const live as long as the reference does.
But does it e.g. matter if the temporary was created in scope of a
function body and has to outlive the function call? And what happens
with this temporary when everything else from the stack has to be
destroyed except the temporary? Is it copied to a new location in memory?

Examples:

int f1()
{
int a=1;
return a;
}

int& f1r() // note that the return type changed
{
int a=1;
return a;
}

int f2()
{
int a(1),b(2);
return a+b;
}

int& f2r()
{
int a(1),b(2);
return a+b;
}

....
/* 1 */ const int& ref = f1();
/* 2 */ const int& ref = f1r();
/* 3 */ const int& ref = f2();
/* 4 */ const int& ref = f2r();
/* 5-8 */ <like 1-4 but without const qualifier>

Can you comment expressions 1-8 regarding their behavior (defined,
undefined) and the lifetime of the objects which are aliased?

Thanks a lot.

--
Matthias Kaeppler
Jul 23 '05 #1
6 1484
Matthias Kaeppler wrote:
I can't find any clear wording on that in the draft standard. Example
12.2 in the standard document illustrates that temporaries bound to
references-to-const live as long as the reference does.
That only refers to a temporary bound _directly_ to a const reference.
But does it e.g. matter if the temporary was created in scope of a
function body and has to outlive the function call?
In a normal execution of the program, a temporary created in the body
of a function cannot outlive the function call. The only way where
a temporary created inside a function can outlive the function by
having a reference bound to it is when an exception is thrown.
And what happens
with this temporary when everything else from the stack has to be
destroyed except the temporary? Is it copied to a new location in
memory?
That's unspecified, IIRC.

Examples:

int f1()
{
int a=1;
return a;
}

int& f1r() // note that the return type changed
{
int a=1;
return a;
Undefined behaviour. You're returning a reference to a local variable.
As soon as the function returns, the reference is invalid.
}

int f2()
{
int a(1),b(2);
return a+b;
}

int& f2r()
{
int a(1),b(2);
return a+b;
Ill-formed. A reference to a non-const object is [attempted to be] bound
to a temporary. Shall not compile (8.5.3/5).
}

...
/* 1 */ const int& ref = f1();
/* 2 */ const int& ref = f1r();
/* 3 */ const int& ref = f2();
/* 4 */ const int& ref = f2r();
/* 5-8 */ <like 1-4 but without const qualifier>

Can you comment expressions 1-8 regarding their behavior (defined,
undefined) and the lifetime of the objects which are aliased?


Cases 1 and 3 have const references bound to temporaries created as
the result of functions returning an object. Those objects live as long
as the references live (in the surrounding scope, which can be as broad
as global). The temporaries are not actually created *inside* the
function.

All other cases either have undefined behavioir because you're returning
a reference to a local object or ill-formed because a non-const reference
cannot be bound to a temporary object.

V
Jul 23 '05 #2
Victor Bazarov wrote:
Matthias Kaeppler wrote:
I can't find any clear wording on that in the draft standard. Example
12.2 in the standard document illustrates that temporaries bound to
references-to-const live as long as the reference does.

That only refers to a temporary bound _directly_ to a const reference.


Do you have the paragaph at hand which backs this statement?

--
Matthias Kaeppler
Jul 23 '05 #3
Victor Bazarov wrote:
Matthias Kaeppler wrote:
I can't find any clear wording on that in the draft standard. Example
12.2 in the standard document illustrates that temporaries bound to
references-to-const live as long as the reference does.

That only refers to a temporary bound _directly_ to a const reference.

But does it e.g. matter if the temporary was created in scope of a
function body and has to outlive the function call?

In a normal execution of the program, a temporary created in the body
of a function cannot outlive the function call. The only way where
a temporary created inside a function can outlive the function by
having a reference bound to it is when an exception is thrown.

And what happens
with this temporary when everything else from the stack has to be
destroyed except the temporary? Is it copied to a new location in
memory?

That's unspecified, IIRC.

Examples:

int f1()
{
int a=1;
return a;
}

int& f1r() // note that the return type changed
{
int a=1;
return a;

Undefined behaviour. You're returning a reference to a local variable.
As soon as the function returns, the reference is invalid.

}

int f2()
{
int a(1),b(2);
return a+b;
}

int& f2r()
{
int a(1),b(2);
return a+b;

Ill-formed. A reference to a non-const object is [attempted to be] bound
to a temporary. Shall not compile (8.5.3/5).

}

...
/* 1 */ const int& ref = f1();
/* 2 */ const int& ref = f1r();
/* 3 */ const int& ref = f2();
/* 4 */ const int& ref = f2r();
/* 5-8 */ <like 1-4 but without const qualifier>

Can you comment expressions 1-8 regarding their behavior (defined,
undefined) and the lifetime of the objects which are aliased?

Cases 1 and 3 have const references bound to temporaries created as
the result of functions returning an object. Those objects live as long
as the references live (in the surrounding scope, which can be as broad
as global). The temporaries are not actually created *inside* the
function.

All other cases either have undefined behavioir because you're returning
a reference to a local object or ill-formed because a non-const reference
cannot be bound to a temporary object.

V


Alright, and what if I change the signature of f1r() to

const int& f1r()

and the signature of f2r() to

const int& f2r()

respectively?
--
Matthias Kaeppler
Jul 23 '05 #4
Matthias Kaeppler wrote:
Victor Bazarov wrote:
Matthias Kaeppler wrote:
I can't find any clear wording on that in the draft standard.
Example 12.2 in the standard document illustrates that temporaries bound
to
references-to-const live as long as the reference does.

That only refers to a temporary bound _directly_ to a const
reference.


Do you have the paragaph at hand which backs this statement?


12.2/5, I believe.

The point of my statement is to say that

const int & i = 5;
const int & j = i;

does not make the temporary '5' persist as long as 'j' lives, only as
long as 'i' lives. IOW, the second initialisation is not "binding of
a temporary to a reference".

V
Jul 23 '05 #5
Matthias Kaeppler wrote:
Victor Bazarov wrote:
Matthias Kaeppler wrote:
I can't find any clear wording on that in the draft standard.
Example 12.2 in the standard document illustrates that temporaries bound
to
references-to-const live as long as the reference does.

That only refers to a temporary bound _directly_ to a const
reference.
But does it e.g. matter if the temporary was created in scope of a
function body and has to outlive the function call?

In a normal execution of the program, a temporary created in the body
of a function cannot outlive the function call. The only way where
a temporary created inside a function can outlive the function by
having a reference bound to it is when an exception is thrown.

And what happens
with this temporary when everything else from the stack has to be
destroyed except the temporary? Is it copied to a new location in
memory?

That's unspecified, IIRC.

Examples:

int f1()
{
int a=1;
return a;
}

int& f1r() // note that the return type changed
{
int a=1;
return a;

Undefined behaviour. You're returning a reference to a local
variable. As soon as the function returns, the reference is invalid.

}

int f2()
{
int a(1),b(2);
return a+b;
}

int& f2r()
{
int a(1),b(2);
return a+b;

Ill-formed. A reference to a non-const object is [attempted to be]
bound to a temporary. Shall not compile (8.5.3/5).

}

...
/* 1 */ const int& ref = f1();
/* 2 */ const int& ref = f1r();
/* 3 */ const int& ref = f2();
/* 4 */ const int& ref = f2r();
/* 5-8 */ <like 1-4 but without const qualifier>

Can you comment expressions 1-8 regarding their behavior (defined,
undefined) and the lifetime of the objects which are aliased?

Cases 1 and 3 have const references bound to temporaries created as
the result of functions returning an object. Those objects live as
long as the references live (in the surrounding scope, which can be
as broad as global). The temporaries are not actually created
*inside* the function.

All other cases either have undefined behavioir because you're
returning a reference to a local object or ill-formed because a
non-const reference cannot be bound to a temporary object.

V


Alright, and what if I change the signature of f1r() to

const int& f1r()

and the signature of f2r() to

const int& f2r()

respectively?

As soon as the function returns and the full expression that contains
that funciton call is evaluated, the temporary is going to be destroyed.
So, in f1r a temporary will be created but will only live long enough
to make it to the outside. A reference initialised from that reference
( /* 2 */ const int& ref = f1r(); ) is still going to be invalid (thus
the program has undefined behaviour). The same with case 4.

V
Jul 23 '05 #6
Matthias Kaeppler wrote:
[...]

Wanted to add that if you wrote

const int& f2r() { int a(1), b(2); return a+b; }

...

const int& ref = f2r() + 0;

you would have a valid and definedly-behaved program because
there would be another temporary created to which 'ref' is bound
and that temporary would persist as long as 'ref' lives.

V
Jul 23 '05 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
by: Mark D. Anderson | last post by:
About a month ago Richard Cornford did an interesting analysis of a memory leak in jscript (internet explorer) when there are "circular" references between DOM objects and (real) jscript objects:...
44
by: Steven T. Hatton | last post by:
This may seem like such a simple question, I should be embarrassed to ask it. The FAQ says an object is "A region of storage with associated semantics." OK, what exactly is meant by "associated...
7
by: simonwittber | last post by:
>>> gen = iterator() >>> gen.next <method-wrapper object at 0x009D1B70> >>> gen.next <method-wrapper object at 0x009D1BB0> >>> gen.next <method-wrapper object at 0x009D1B70> >>> gen.next...
2
by: Aaron | last post by:
I have a data sructure setup and I populate it in a loop like so: y=0 while X: DS.name = "ASDF" DS.ID = 1234 list = DS; y = y + 1
17
by: Divick | last post by:
Hi, I am designing an API and the problem that I have is more of a design issue. In my API say I have a class A and B, as shown below class A{ public: void doSomethingWithB( B * b) { //do...
9
by: DrConti | last post by:
Dear Python developer community, I'm quite new to Python, so perhaps my question is well known and the answer too. I need a variable alias ( what in other languages you would call "a pointer"...
10
by: Hendri Adriaens | last post by:
Hi, I'm trying to automate the creation of an excel file via COM. I copied my code below. I read many articles about how to release the COM objects that I create. The code below runs just fine...
5
by: Giovanni Dicanio | last post by:
Hi, please consider the following scenario: I allocate some objects in C# using new. e.g.: MyObject x = new MyObject(); then I assign this object to several places, e.g. in Tag field in
275
by: Astley Le Jasper | last post by:
Sorry for the numpty question ... How do you find the reference name of an object? So if i have this bob = modulename.objectname() how do i find that the name is 'bob'
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
1
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
1
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...

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.