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 6 1415
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
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
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
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
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
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 This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
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:...
|
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...
|
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...
|
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
|
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...
|
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"...
|
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...
|
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
|
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'
|
by: Kemmylinns12 |
last post by:
Blockchain technology has emerged as a transformative force in the business world, offering unprecedented opportunities for innovation and efficiency. While initially associated with cryptocurrencies...
|
by: antdb |
last post by:
Ⅰ. Advantage of AntDB: hyper-convergence + streaming processing engine
In the overall architecture, a new "hyper-convergence" concept was proposed, which integrated multiple engines and...
|
by: Matthew3360 |
last post by:
Hi there. I have been struggling to find out how to use a variable as my location in my header redirect function.
Here is my code.
header("Location:".$urlback);
Is this the right layout the...
|
by: AndyPSV |
last post by:
HOW CAN I CREATE AN AI with an .executable file that would suck all files in the folder and on my computerHOW CAN I CREATE AN AI with an .executable file that would suck all files in the folder and...
|
by: Arjunsri |
last post by:
I have a Redshift database that I need to use as an import data source. I have configured the DSN connection using the server, port, database, and credentials and received a successful connection...
|
by: Oralloy |
last post by:
Hello Folks,
I am trying to hook up a CPU which I designed using SystemC to I/O pins on an FPGA.
My problem (spelled failure) is with the synthesis of my design into a bitstream, not the C++...
|
by: BLUEPANDA |
last post by:
At BluePanda Dev, we're passionate about building high-quality software and sharing our knowledge with the community. That's why we've created a SaaS starter kit that's not only easy to use but also...
|
by: Rahul1995seven |
last post by:
Introduction:
In the realm of programming languages, Python has emerged as a powerhouse. With its simplicity, versatility, and robustness, Python has gained popularity among beginners and experts...
|
by: Ricardo de Mila |
last post by:
Dear people, good afternoon...
I have a form in msAccess with lots of controls and a specific routine must be triggered if the mouse_down event happens in any control.
Than I need to discover what...
| |