473,414 Members | 1,750 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,414 software developers and data experts.

Returning reference to local variable - is this okay?

Hi, I have tried to find an answer to the this question on the internet but can't. The compiler gives a warning, but this program works okay.

Expand|Select|Wrap|Line Numbers
  1. int &f()
  2. {
  3.     int c=4;
  4.     return c;
  5. }
  6. int main()
  7. {
  8.     int b=f();
  9.     cout<<b;
  10. }
Is there anything bad about this, or is this a disaster waiting to happen? I think it depends on whether variable c is still in existence when the return was made. One book I was reading said that all function variables except the return variable were destroyed BEFORE the return was made, in that case this program shouldn't work - or should it???? Thankyou in advance.
Aug 6 '07 #1
9 7547
RedSon
5,000 Expert 4TB
Hi, I have tried to find an answer to the this question on the internet but can't. The compiler gives a warning, but this program works okay.

Expand|Select|Wrap|Line Numbers
  1. int &f()
  2. {
  3.     int c=4;
  4.     return c;
  5. }
  6. int main()
  7. {
  8.     int b=f();
  9.     cout<<b;
  10. }
Is there anything bad about this, or is this a disaster waiting to happen? I think it depends on whether variable c is still in existence when the return was made. One book I was reading said that all function variables except the return variable were destroyed BEFORE the return was made, in that case this program shouldn't work - or should it???? Thankyou in advance.
Why is your method signature &f() ?
Aug 6 '07 #2
Good question... Did you mean "int& f()", that is a whole different thing for the brain-based parser.

That aside, I'd say the answer to the "a disaster waiting to happen" question is "definitely yeah". When the function returns int&, it returns not the value of c, but the reference of c; since c is declared locally, it's also destroyed when it goes out of scope, as expected. So now you are indeed returning a pointer to an unallocated memory zone. In this situation, two things might happen:
  1. The call to f and the actual use of the return value (which, I stress again, is a reference and not the actual content of the referenced variable) are very close to each other, time wise; the memory zone previously used by the call to f is still untouched. As such, the old value of c is at the proper place and it can be read in main. That's why the program works.
  2. The call to f and the actual use of the return value are a long time from each other. With this, the probabilities increase that somebody else has claimed that particular bit of free memory, and the contents of the old &c are no longer there; but the calling code doesn't know that, so it just goes on.
And that's the gist of it. The program might function perfectly, might cause a fatal error, it might work without a glitch and cause sudden death 5 instructions later, or whatever else fancies it. It all depends on exactly what data overwrote the old c. In Jargon file parlance, this would be a heisenbug...
Aug 6 '07 #3
JosAH
11,448 Expert 8TB
Hi, I have tried to find an answer to the this question on the internet but can't. The compiler gives a warning, but this program works okay.

Expand|Select|Wrap|Line Numbers
  1. int &f()
  2. {
  3.     int c=4;
  4.     return c;
  5. }
  6. int main()
  7. {
  8.     int b=f();
  9.     cout<<b;
  10. }
Is there anything bad about this, or is this a disaster waiting to happen? I think it depends on whether variable c is still in existence when the return was made. One book I was reading said that all function variables except the return variable were destroyed BEFORE the return was made, in that case this program shouldn't work - or should it???? Thankyou in advance.
Yes it's bad; very bad, because local variables cease to exist after the function
returned and you pass a reference back to something that doesn't exist anymore.
It's just undefined behaviour according to the Standard. In other words: bad.

kind regards,

Jos
Aug 6 '07 #4
Darryl
86
It's undefined behavior and not guaranteed to work.

The fact is that the reference is pointing somewhere, and that somewhere can be output and in a trivial program like your example that somewhere is likely to be equal to the same thing it was when used... But there's nothing protecting that somewhere from getting overwritten later in your program which in a larger program would more likely happen and then you'd have problems.
Aug 6 '07 #5
Sorry this post is somewhat old but I have the same question. I understand why this is problematic. However I am uncertain how to do this better.

Expand|Select|Wrap|Line Numbers
  1. int & f()
  2. {
  3.    int c=4;
  4.    return c;
  5. }
  6. int main()
  7. {
  8.     int b=f();
  9.     cout<<b;
  10. }
I think that I can do this however I am not sure what the implications would be:

Expand|Select|Wrap|Line Numbers
  1. int & f()
  2. {
  3.    int c = new int(4);
  4.    return c;
  5. }
  6. int main()
  7. {
  8.     int b=f();
  9.     cout<<b;
  10. }
I think that this creates the new variable c on the system heap as oposed to the stack. I think that c will never go away unless the user explicitly tells c to die. (I think that there is a free keyword or something that releases things that where created with new).
Nov 14 '08 #6
disown
17
For your example, the best thing is probably to return by value directly (i.e "int f()"), since we are dealing with simple data types, which are cheap to copy.

For larger data types, you have to choose between copying or allocating dynamically. Dynamic memory gets tricky since you need to delete it when it is no longer used. The general recommendation is to use classes (constructors and destructors) to manage this. This idiom is called RAII. With this approach, you only use "new" or "delete" within constructors and destructors (naturally with some exceptions).
Nov 14 '08 #7
donbock
2,426 Expert 2GB
I think that this creates the new variable c on the system heap as opposed to the stack. I think that c will never go away unless the user explicitly tells c to die. (I think that there is a free keyword or something that releases things that where created with new).
So ... you're hoping that by making c a persistent variable you'll avoid undefined behavior. Sometimes that's exactly the right thing to do: when the purpose of your function is to create an instance of some type. Is that what your function is for?

If all you're doing is allocating a persistent variable so you can return a value then you're going through a lot of trouble risking undefined behavior to do something that could be accomplished much easier by changing the function to return an int rather than the address of an int.

As for your immediate question, I don't know if your proposed syntax will actually create a persistent variable.
Nov 14 '08 #8
disown
17
I also don't think there is any way in C++ to pass a reference to a function, and then construct a variable directly into that memory space, thus you may not fiddle with the callers stack (maybe someone knows more about this?).

Also see return by value faq
Nov 14 '08 #9
Savage
1,764 Expert 1GB
You could always try using static.

Expand|Select|Wrap|Line Numbers
  1. int & f()
  2. {
  3.    static int c = new int(4);
  4.    return c;
  5. }
  6. int main()
  7. {
  8.     int b=f();
  9.     cout<<b;
  10. }
Nov 14 '08 #10

Sign in to post your reply or Sign up for a free account.

Similar topics

7
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 :...
13
by: Matthias Kaeppler | last post by:
Hi, I was wondering why library implementors often make getter functions return strings by value (copies). For example, in boost::filesystem the leaf() function returns an std::string by value....
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...
6
by: Generic Usenet Account | last post by:
Is it okay to return a local datastructure (something of type struct) from a function, as long as it does not have any pointer fields? I think it is a bad idea, but one of my colleagues does not...
6
by: EvilOldGit | last post by:
const Thing &operator++(int) { Thing temp = *this; operator++(); return temp; } Is this code robust ? I get a compiler warning about returning a reference to a a local, which I guess is...
11
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++
7
by: pauldepstein | last post by:
#include <iostream> using namespace std; double & GetWeeklyHours() { double h = 46.50; double &hours = h; return hours; }...
23
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...
8
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
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
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,...
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
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: 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...

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.