2

In the following code, a string str is created in fun() and as fun() ends, the variable goes out of scope. So, the reference to it should be invalid and throw some errors or garbage value. But this program runs fine. Why? I expected some error as the reference to a local variable of fun() was returned but the code runs fine.

#include <iostream> 
using namespace std; 
string& fun(){
    string str="ag";
    string &q=str;
    cout<<q<<" "<<&q<<endl;
    return q;
}
int main(){
    string &s=fun();
    cout<<s<<" "<<&s<<endl;
    return 0;

}
greywolf82
  • 21,813
  • 18
  • 54
  • 108
  • 4
    It's undefined behavior to take a reference to an object that no longer exists, so anything can happen, including working correctly (sometimes). – gct Jan 03 '20 at 18:36
  • 3
    Welcome to the wonderful world of [*undefined behavior*](https://en.wikipedia.org/wiki/Undefined_behavior). Sometimes things seems to work, and in the next it just wont. – Some programmer dude Jan 03 '20 at 18:36
  • And the time after that the nasal demons take flight! – user4581301 Jan 03 '20 at 18:44
  • It's technically undefined behavior as others have pointed out. The reason why it "sort of works" is likely because the stack memory allocated for `str` in `fun()` hasn't been overridden. If you were to insert almost any other function call between the invocation of `fun` and `cout`, you'd see garbage data. Try invoking, `printf("%s\n", s.c_str())` right before `cout`. The printf call would likely trash the stack and variables referenced into it. – selbie Jan 03 '20 at 18:45
  • *i expected some error as the referance to a local variable of fun() was returned but the code runs fine* -- I tied 1200 pounds to a rope, but I expected the rope to break because it is only rated for 1000 pounds. – PaulMcKenzie Jan 03 '20 at 18:46
  • I tried your code. It just printed out `puppies puppies puppies` continuously scrolling by on the terminal until I hit control-C. A good indicator of _undefined behavior_. If you enable your compiler's warnings (I used `-Wreturn-stack-address`), it may very likely warn of the problem. – Eljay Jan 03 '20 at 19:20

2 Answers2

1

What a reference refers to does not outlive the actual object.

In your fun function you are returning a reference to an object that is about to go out of scope / be destroyed. That's not going to end well.

But, since what you are doing is Undefined Behaviour; any result is OK. But you have no guarantee what that result may be.

A reference is just an alias for something else. It doesn't keep what it refers to alive.

Jesper Juhl
  • 30,449
  • 3
  • 47
  • 70
0

So, the reference to it should be invalid and throw some errors or garbage value.

Not quite. Yes, the reference is invalidated, but that doesn't mean you will get an error or garbage.

Undefined Behavior allows anything to happen. This is really nasty because not only is an error a possible outcome, but appearing to work properly is in the realm of possibilities.

This is generally why everyone says avoid Undefined Behavior at all costs, because you can end up in situations where your code appears to work, but then one day suddenly crashes for no apparent reason. If your code has Undefined Behavior, then even if it works, it will not be guaranteed to always work the same way.


Note: your compiler might warn you about things like this. So you could consider that an "error," but I don't think that's what you mean.

The good news is, while I don't know if it is guaranteed to give you a warning for that, I believe most modern compilers will warn you. So if you pay attention to warnings, you won't ever have to worry about stuff this slipping through.