473,467 Members | 1,291 Online
Bytes | Software Development & Data Engineering Community
Create Post

Home Posts Topics Members FAQ

Function returning a reference



unsigned int CheesePlain(void)
{
unsigned int const chalk = 42;

return chalk;
}
unsigned int& CheeseRef(void)
{
unsigned int const chalk = 42;

return chalk;
}
int main(void)
{
unsigned int plain = CheesePlain();

unsigned int ref = CheeseRef();
}

Now, consider that the return type is not unsigned int, but some other class
name that prints out stuff via cout in its constructor, copy constructor,
assignment operator. Will you find that there's a difference in the two
separate printouts, ie. that the "plain" one will create one more temporary
than the reference version?
-JKop
Jul 22 '05 #1
6 1695
JKop wrote:
<snip>

unsigned int& CheeseRef(void)
{
unsigned int const chalk = 42;

return chalk;
}
Very bad. This function returns a reference to an object that is destroyed
right after return.


int main(void)
{
unsigned int plain = CheesePlain();

unsigned int ref = CheeseRef();
'ref' is not a reference:
unsigned int& ref = CheeseRef();
But the returned reference is still invalid.
}

Now, consider that the return type is not unsigned int, but some
other class name that prints out stuff via cout in its constructor,
copy constructor, assignment operator. Will you find that there's a
difference in the two separate printouts, ie. that the "plain" one
will create one more temporary than the reference version?
Doesn't matter, since it's incorrect code. ;)

- Pete


-JKop


Jul 22 '05 #2
JKop wrote:
unsigned int CheesePlain(void)
{
unsigned int const chalk = 42;

return chalk;
}
unsigned int& CheeseRef(void)
{
unsigned int const chalk = 42;

return chalk;
}

I imagine a worthwhile compiler will not compile CheeseRef, at least not
without giving you quite a few warnings. First, the return type is not
const correct. Second, you are returning a reference to a local variable.

int main(void)
{
unsigned int plain = CheesePlain();

unsigned int ref = CheeseRef();
}

Now, consider that the return type is not unsigned int, but some other class
name that prints out stuff via cout in its constructor, copy constructor,
assignment operator. Will you find that there's a difference in the two
separate printouts, ie. that the "plain" one will create one more temporary
than the reference version?
-JKop

Let me propose a slight modification that may or may not provide the
answers you are wanting.

unsigned int CheesePlain()
{
unsigned int const chalk = 42;

return chalk;
}

int main(void)
{
unsigned int &ref = CheesePlain();
unsigned int plain = CheesePlain();
}
I've swapped the order because I want to talk about them in this order.
The first assignment creates a temporary, and copies the value of
'chalk' into it. If, as you propose, these were objects with
constructors, the temporary's copy constructor would be called. The
lifetime of the temporary is the same as the lifetime of the reference
bound to it, so when ref goes out of scope at the end of main, the
destructor should be called.

The second assignment is actually a bit more complicated, and the
precise behavior is not defined. One version of what could happen goes
like this. A temporary is created to hold the return value, and 'chalk'
is copied into it (copy constructor). Then, the temporary is used to
initialize 'plain' (copy constructor). The temporary then gets
destroyed, and its destructor is called. However, the implementation is
allowed (but not required) to construct the return value directly into
'plain', *even if the copy constructor or destructor have side effects*
(such as printing something)! So, depending on your implementation, you
may or may not see the temporary getting constructed and destructed.

Alan
Jul 22 '05 #3
Alan Johnson wrote:
JKop wrote:
unsigned int CheesePlain(void)
{
unsigned int const chalk = 42;

return chalk;
}
unsigned int& CheeseRef(void)
{
unsigned int const chalk = 42;

return chalk;
}


I imagine a worthwhile compiler will not compile CheeseRef, at least not
without giving you quite a few warnings. First, the return type is not
const correct. Second, you are returning a reference to a local variable.

int main(void)
{
unsigned int plain = CheesePlain();

unsigned int ref = CheeseRef();
}

Now, consider that the return type is not unsigned int, but some other
class name that prints out stuff via cout in its constructor, copy
constructor, assignment operator. Will you find that there's a
difference in the two separate printouts, ie. that the "plain" one
will create one more temporary than the reference version?
-JKop


Let me propose a slight modification that may or may not provide the
answers you are wanting.

unsigned int CheesePlain()
{
unsigned int const chalk = 42;

return chalk;
}

int main(void)
{
unsigned int &ref = CheesePlain();
unsigned int plain = CheesePlain();
}
I've swapped the order because I want to talk about them in this order.
The first assignment creates a temporary, and copies the value of
'chalk' into it. If, as you propose, these were objects with
constructors, the temporary's copy constructor would be called. The
lifetime of the temporary is the same as the lifetime of the reference
bound to it, so when ref goes out of scope at the end of main, the
destructor should be called.

The second assignment is actually a bit more complicated, and the
precise behavior is not defined. One version of what could happen goes
like this. A temporary is created to hold the return value, and 'chalk'
is copied into it (copy constructor). Then, the temporary is used to
initialize 'plain' (copy constructor). The temporary then gets
destroyed, and its destructor is called. However, the implementation is
allowed (but not required) to construct the return value directly into
'plain', *even if the copy constructor or destructor have side effects*
(such as printing something)! So, depending on your implementation, you
may or may not see the temporary getting constructed and destructed.

Alan

As a followup, here is what the standard has to say about it. Excerpt
from 12.8/15 :

"This elision of copy operations is permitted in the following
circumstances (which may be combined to eliminate multiple copies):

— in a return statement in a function with a class return type, when the
expression is the name of a non-volatile automatic object with the same
cv-unqualified type as the function return type, the copy operation can
be omitted by constructing the automatic object directly into the
function’s return value

— when a temporary class object that has not been bound to a reference
(12.2) would be copied to a class object with the same cv-unqualified
type, the copy operation can be omitted by constructing the temporary
object directly into the target of the omitted copy"

Alan
Jul 22 '05 #4
>unsigned int &ref = CheesePlain();

Doesn't this need to be a reference to const in order for the temporary to be
bound to it?
Jul 22 '05 #5
Alan Johnson wrote in news:40********@news.ua.edu in comp.lang.c++:
int main(void)
{
unsigned int &ref = CheesePlain();
unsigned int plain = CheesePlain();
}
I've swapped the order because I want to talk about them in this order.
The first assignment creates a temporary, and copies the value of
'chalk' into it. If, as you propose, these were objects with
constructors, the temporary's copy constructor would be called. The
lifetime of the temporary is the same as the lifetime of the reference
bound to it, so when ref goes out of scope at the end of main, the
destructor should be called.


Maybe I've missed someting up-thread, but if this is meant to be C++
the first line of main() needs to be:

unsigned int const &ref = CheesePlain();

As temporaries can't be *bound* to non-constant references.

Note: Some compiler (MSVC) allow the above non-standard code as
a so called "language extension".

Rob.
--
http://www.victim-prime.dsl.pipex.com/
Jul 22 '05 #6
DaKoadMunky wrote:
unsigned int &ref = CheesePlain();

Doesn't this need to be a reference to const in order for the temporary to be
bound to it?


Absolutely. That was an oversight on my part. Thanks for the correction.

Alan
Jul 22 '05 #7

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

Similar topics

6
by: Krackers | last post by:
How do you write a function which returns a reference to an array. I can only get a function to return a copy of the array itself. I've had a look at some other threads in this group an the return...
7
by: Pablo J Royo | last post by:
Hello: i have a function that reads a file as an argument and returns a reference to an object that contains some information obtained from the file: FData &ReadFile(string FilePath); But ,...
12
by: Olumide | last post by:
I'm studying Nigel Chapman's Late Night Guide to C++ which I think is an absolutely fantastic book; however on page 175 (topic: operator overlaoding), there the following code snippet: inline...
14
by: lutorm | last post by:
Hi, I'm having a problem with a return statement being parsed to return a function (I think). Check here: template <typename T> class A {}; template <typename T> class maker_of_A { public:...
5
by: Alfonso Morra | last post by:
Hi, What is the recomended way of returning an STL container (e.g. std::string, std::vector etc fom a function? Is it by simply returning a local variable? (I doubt it) std::string...
14
by: Mike Labosh | last post by:
How do you define whether the return value of a function is ByRef or ByVal? I have a utility class that cleans imported records by doing *really heavy* string manipulation in lots of different...
2
by: Tany | last post by:
How can I declare function returning array of Integer pointers . Please help !!
12
by: ypjofficial | last post by:
Hello All, I need to return a vector from a function.The vector is of int and it can contain as many as 1000 elements.Earlier I was doing //function definition vector<intretIntVector() {...
6
by: Matthew Cook | last post by:
I would like to overload the unary minus operator so that I can negate an instance of a class and pass that instance to a function without creating an explicit temporary variable. Here is an...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
1
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
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
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
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...
0
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
0
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated ...

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.