473,804 Members | 3,204 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Returning a reference to a local variable

#include <iostream>
using namespace std;

double & GetWeeklyHours( )
{
double h = 46.50;
double &hours = h;
return hours;
}
//---------------------------------------------------------------------------
int main()
{
double hours = GetWeeklyHours( );

cout << "Weekly Hours: " << hours << endl;

return 0;
}
According to a (hopefully reliable) website, the above is correct
code.

Why is the above _not_ an example of the sin of "returning a reference
to a local variable"? What is the difference between the return-
reference-to-local problem and the above code?

Thanks,

Paul Epstein
Dec 30 '07 #1
7 6686
On Dec 29, 10:40 pm, pauldepst...@at t.net wrote:
#include <iostream>
using namespace std;

double & GetWeeklyHours( )
{
double h = 46.50;
double &hours = h;
return hours;}

//---------------------------------------------------------------------------
int main()
{
double hours = GetWeeklyHours( );

cout << "Weekly Hours: " << hours << endl;

return 0;

}

According to a (hopefully reliable) website, the above is correct
code.

Why is the above _not_ an example of the sin of "returning a reference
to a local variable"? What is the difference between the return-
reference-to-local problem and the above code?
It is an example of undefined behaviour. A compiler is not required to
generate a diagnostic either.
Is it accepteable? Not in a long shot.
Here, try the following and pay attention to the output and sequence
of events.

#include <iostream>

class Hours
{
double m_d;
public:
Hours() : m_d(0.0) { std::cout << "Hours()\n" ; }
Hours(double d) : m_d(d) { std::cout << "Hours(double)\ n"; }
~Hours() { std::cout << "~Hours()\n "; }
Hours(const Hours& copy)
{
std::cout << "Hours(cons t Hours& copy)\n";
m_d = copy.m_d;
}
double get() const { return m_d; }
};

Hours& GetWeeklyHours( )
{
Hours h = 46.50;
std::cout << "local initialized\n";
Hours& hours = h;
std::cout << "reference set\n";
return hours;
}

//---------------------------------------------------------------------------
int main()
{
Hours hours = GetWeeklyHours( ); // is a copy (1)

std::cout << "Weekly Hours: " << hours.get() << std::endl;
}

/*
Hours(double)
local initialized
reference set
~Hours() // local destroyed here
Hours(const Hours& copy) // is a copy (1) of a reference
Weekly Hours: 6.95329e-310
~Hours()
*/

The basic rule of thumb is: if a local invokes a default or
parametized ctor, not a copy, it only lives in that scope.
It doesn't matter whether you use a reference, a 'reference to const'
or a 'pointer to const', the residual garbage left over from the
destruction of the local variable can't be guarenteed. Anything can
happen.

this is fine, btw:
Hours GetWeeklyHours( )
{
return Hours(46.5);
}

but this is not:
Hours const& GetWeeklyHours( )
{
return Hours(46.5);
}

Dec 30 '07 #2
On Dec 30, 1:00*pm, Salt_Peter <pj_h...@yahoo. comwrote:
On Dec 29, 10:40 pm, pauldepst...@at t.net wrote:


#include <iostream>
using namespace std;
double & GetWeeklyHours( )
{
* * double h = 46.50;
* * double &hours = h;
* * return hours;}
//-------------------------------------------------------------------------*--
int main()
{
* * double hours = GetWeeklyHours( );
* * cout << "Weekly Hours: " << hours << endl;
* * return 0;
}
According to a (hopefully reliable) website, the above is correct
code.
Why is the above _not_ an example of the sin of "returning a reference
to a local variable"? *What is the difference between the return-
reference-to-local problem and the above code?

It is an example of undefined behaviour. A compiler is not required to
generate a diagnostic either.
Is it accepteable? Not in a long shot.
Here, try the following and pay attention to the output and sequence
of events.

#include <iostream>

class Hours
{
* double m_d;
public:
* Hours() : m_d(0.0) { std::cout << "Hours()\n" ; }
* Hours(double d) : m_d(d) { std::cout << "Hours(double)\ n"; }
* ~Hours() { std::cout << "~Hours()\n "; }
* Hours(const Hours& copy)
* {
* * std::cout << "Hours(cons t Hours& copy)\n";
* * m_d = copy.m_d;
* }
* double get() const { return m_d; }

};

Hours& GetWeeklyHours( )
{
* Hours h = 46.50;
* std::cout << "local initialized\n";
* Hours& hours = h;
* std::cout << "reference set\n";
* return hours;

}

//-------------------------------------------------------------------------*--
int main()
{
* Hours hours = GetWeeklyHours( ); // is a copy (1)

* std::cout << "Weekly Hours: " << hours.get() << std::endl;

}

/*
Hours(double)
local initialized
reference set
~Hours() // local destroyed here
Hours(const Hours& copy) // is a copy (1) of a reference
Weekly Hours: 6.95329e-310
~Hours()
*/

The basic rule of thumb is: if a local invokes a default or
parametized ctor, not a copy, it only lives in that scope.
It doesn't matter whether you use a reference, a 'reference to const'
or a 'pointer to const', the residual garbage left over from the
destruction of the local variable can't be guarenteed. Anything can
happen.

this is fine, btw:
Hours GetWeeklyHours( )
{
* return Hours(46.5);

}

but this is not:
Hours const& GetWeeklyHours( )
{
* return Hours(46.5);

}- Hide quoted text -

- Show quoted text -- Hide quoted text -

- Show quoted text -
Thanks, Peter. You seem to have put a lot of time and effort towards
helping me and I appreciate that. However, I'm still a bit confused.
I understand why your example code is bugged. The mystery (to me) is
why the code I posted originally _does not_ appear to suffer from the
reference-to-local bug. It works on my compiler, and was copied from
what seemed like a decent website. Are you saying that my original
code suffers from the same bug but that sometimes the local is
destroyed at a late enough time so that the original code still gives
correct results? My question is: Why does the original code give
reliable results even though it appears to return a reference to a
local?

Paul Epstein
Dec 30 '07 #3
On 2007-12-29 22:40:31 -0500, pa**********@at t.net said:
#include <iostream>
using namespace std;

double & GetWeeklyHours( )
{
double h = 46.50;
double &hours = h;
return hours;
}
//---------------------------------------------------------------------------
int main()
{
double hours = GetWeeklyHours( );

cout << "Weekly Hours: " << hours << endl;

return 0;
}
According to a (hopefully reliable) website, the above is correct
code.
No. As far as I know, the standard makes no guarantee a behavior for
this code. This is no correct code.

BTW, please give the link to that website.

--

-kira

Dec 30 '07 #4
On Dec 30, 1:31*pm, Kira Yamato <kira...@earthl ink.netwrote:
On 2007-12-29 22:40:31 -0500, pauldepst...@at t.net said:


#include <iostream>
using namespace std;
double & GetWeeklyHours( )
{
* * double h = 46.50;
* * double &hours = h;
* * return hours;
}
//-------------------------------------------------------------------------*--
int main()
{
* * double hours = GetWeeklyHours( );
* * cout << "Weekly Hours: " << hours << endl;
* * return 0;
}
According to a (hopefully reliable) website, the above is correct
code.

No. *As far as I know, the standard makes no guarantee a behavior for
this code. *This is no correct code.

BTW, please give the link to that website.

--

-kira- Hide quoted text -

- Show quoted text -
Thanks Kira and Peter

The link is http://www.functionx.com/cpp/example...nreference.htm
The reason I was reluctant to include the link at the beginning is
that I didn't want to be seen as unfairly accusing the people who
designed the website.

Paul Epstein
Dec 30 '07 #5
On Dec 30, 12:31 am, pauldepst...@at t.net wrote:
On Dec 30, 1:00 pm, Salt_Peter <pj_h...@yahoo. comwrote:
On Dec 29, 10:40 pm, pauldepst...@at t.net wrote:
#include <iostream>
using namespace std;
double & GetWeeklyHours( )
{
double h = 46.50;
double &hours = h;
return hours;}
//-------------------------------------------------------------------------*--
int main()
{
double hours = GetWeeklyHours( );
cout << "Weekly Hours: " << hours << endl;
return 0;
}
According to a (hopefully reliable) website, the above is correct
code.
Why is the above _not_ an example of the sin of "returning a reference
to a local variable"? What is the difference between the return-
reference-to-local problem and the above code?
It is an example of undefined behaviour. A compiler is not required to
generate a diagnostic either.
Is it accepteable? Not in a long shot.
Here, try the following and pay attention to the output and sequence
of events.
#include <iostream>
class Hours
{
double m_d;
public:
Hours() : m_d(0.0) { std::cout << "Hours()\n" ; }
Hours(double d) : m_d(d) { std::cout << "Hours(double)\ n"; }
~Hours() { std::cout << "~Hours()\n "; }
Hours(const Hours& copy)
{
std::cout << "Hours(cons t Hours& copy)\n";
m_d = copy.m_d;
}
double get() const { return m_d; }
};
Hours& GetWeeklyHours( )
{
Hours h = 46.50;
std::cout << "local initialized\n";
Hours& hours = h;
std::cout << "reference set\n";
return hours;
}
//-------------------------------------------------------------------------*--
int main()
{
Hours hours = GetWeeklyHours( ); // is a copy (1)
std::cout << "Weekly Hours: " << hours.get() << std::endl;
}
/*
Hours(double)
local initialized
reference set
~Hours() // local destroyed here
Hours(const Hours& copy) // is a copy (1) of a reference
Weekly Hours: 6.95329e-310
~Hours()
*/
The basic rule of thumb is: if a local invokes a default or
parametized ctor, not a copy, it only lives in that scope.
It doesn't matter whether you use a reference, a 'reference to const'
or a 'pointer to const', the residual garbage left over from the
destruction of the local variable can't be guarenteed. Anything can
happen.
this is fine, btw:
Hours GetWeeklyHours( )
{
return Hours(46.5);
}
but this is not:
Hours const& GetWeeklyHours( )
{
return Hours(46.5);
}- Hide quoted text -
- Show quoted text -- Hide quoted text -
- Show quoted text -

Thanks, Peter. You seem to have put a lot of time and effort towards
helping me and I appreciate that. However, I'm still a bit confused.
I understand why your example code is bugged. The mystery (to me) is
why the code I posted originally _does not_ appear to suffer from the
reference-to-local bug. It works on my compiler, and was copied from
what seemed like a decent website. Are you saying that my original
code suffers from the same bug but that sometimes the local is
destroyed at a late enough time so that the original code still gives
correct results? My question is: Why does the original code give
reliable results even though it appears to return a reference to a
local?

Paul Epstein
First off - you may very well find others to have a different point of
view than mine.
You might even find a compiler with some scheme that makes the above
work with primitives (stored in a register? who knows - i really don't
care).

The fact remains, once the scope ends:
a) the local variable is no more
b) that area of memory is therefore left unprotected (its writeable)

So if you have a busy program (multi-threaded, etc)... its only a
question of time.
Debugging an issue that only happens intermittently is near
impossible. Testing for UB is easy comparatively.

A completely different Issue...
The standard specifically says you can't bind a 'reference to non-
const' to a temporary. Many beleive this means that its ok to *return*
a local through a reference to const. Well, not quite. The standard,
as i understand it, says this:

void DisplayHours(co nst double& ref) // must be a ref to const
{
std::cout << ref << std::endl;
}

int main()
{
DisplayHours(do uble(99));
}

The above works because double(99), a temporary, has a lifetime that
lasts until the function ceases to exist.
That, by the way, is the better way to write your GetWeeklyHours
function, pass the variable by reference_to_co nst which safely
modifies the original. At least thats guarenteed 100% of the time.

Hopefully, a little light was thrown on this and if not, someone else
can give it a go.
Dec 30 '07 #6
pa**********@at t.net wrote:
#include <iostream>
using namespace std;

double & GetWeeklyHours( )
{
double h = 46.50;
double &hours = h;
return hours;
}
//---------------------------------------------------------------------------
int main()
{
double hours = GetWeeklyHours( );

cout << "Weekly Hours: " << hours << endl;

return 0;
}
According to a (hopefully reliable) website, the above is correct
code.

Why is the above _not_ an example of the sin of "returning a reference
to a local variable"? What is the difference between the return-
reference-to-local problem and the above code?
As I understand it, the example code works because RVO constructs the
local variable at the site of main's 'hours' variable.

Without RVO, the above code would not work, and RVO cannot be guaranteed.
Dec 30 '07 #7
Daniel T. wrote:
>
As I understand it, the example code works because RVO constructs the
local variable at the site of main's 'hours' variable.

Without RVO, the above code would not work, and RVO cannot be guaranteed.
Well more likely, the RVO just causes the copy to the main:hours
variable before the GetWeeklyHours: h is obliterated.

One of those insidious forms of undefined behavior is things appear to
work normally, TODAY.
Dec 30 '07 #8

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

Similar topics

6
14037
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 value of a function acts like 'by Val' returning the value only (except for objects) can you make it return a reference instead? cheers, Krackers
1
7428
by: Andrew Fleet | last post by:
Hi, I'm looking at returning a reference to an array I create within a subroutine. I could do this... sub foo { my @theArray; <snip>
7
3863
by: Dr John Stockton | last post by:
What are the best ways of returning multiple results from a subroutine ? I've been using ... return } which is inelegant. I'm used to Pascal's procedure X(const A, B : integer; var C, D : byte) ; where A, B are inputs only, and C, D are in/out.
12
3296
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 MFVec operator+(const MFVec& z1, const MFVec& z2) // Global function { MFVec res = z1; res += z2 return res; // WHY???
5
2279
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 foo(const std::string& rhs) { std::string var = rhs ; var += " received" ;
17
3240
by: djcredo | last post by:
Hey all, I want to return a pointer to a struct. Here is what I'lm trying to do: struct Position{ int x; int y; }; Position* GraphicTag::getRenderCentre(){
11
2289
by: ravi | last post by:
Can anybody out there tell me whether it i possible to return a reference from a function in C++ I am using Turbo C++
23
2946
by: pauldepstein | last post by:
Below is posted from a link for Stanford students in computer science. QUOTE BEGINS HERE Because of the risk of misuse, some experts recommend never returning a reference from a function or method. QUOTE ENDS HERE I have never heard anyone else say that it is a problem for a function
8
2221
by: darren | last post by:
Hi everybody, have a quick look at this code: ===== ===== int main(void) { string msg; makeString(msg); cout << "back in main, result = " << msg << endl;
0
9706
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, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
10332
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 tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
10321
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 Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
10077
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 protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
9152
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, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
6853
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5522
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
1
4300
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 we have to send another system
3
2991
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

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.