When I run my code, attempting to return a local variable:
#include<iostream>
using namespace std;
int &fun()
{
int x = 30;
return x;
}
int main()
{
fun() = 10;
cout << fun();
return 0;
}
why does some compiler output 0 and some are 30
Returning a reference to a local variable that subsequently goes out of scope is undefined behaviour in C++.
Sometimes it might work, sometimes it might not. Occasionally the compiler might eat your cat.
Related
This has bothered me, I have just gotten back into c++ lately, and am well aware of references. Why does it seem there is no difference between b and c below. In other words, intuitively I would think c not being a ref variable would take a copy. It got me thinking when considering the problem of returning a reference to a local variable.
int a = 10;
int& func()
{
return a;
}
int &b = func();
int c = func(); // shouldn't this make a copy into c but c acts like a reference.
I would think c not being a ref variable would take a copy.
c is indeed a copy of a. Note that int c = func(); is copy initialization while int &b = func(); is reference initialization.
This means that if you make changes to c they will not be reflected on a. Demo
int a = 10;
int& func()
{
return a;
}
int &b = func(); //reference initialization
int c = func(); //copy initialization
int main()
{
c = 20;
std::cout << a<< " "<< b <<" "<< c <<std::endl; // 10 10 20
return 0;
}
Note also the emphasis on "initialization" instead of "assignment". These terms have different meaning in C++ unlike other languages(python for instance).
Thanks for the answers, makes sense now. This question started from "why can't I return a local variable reference to a variable if its a copy?" Well, I realized because its too late at that point - the stack is gone. I was thinking the copy could be made before the stack went away - wrong!
You can return to a reference but when you use it, segfault.
Return to a variable and, segfault immediately since it tries to copy.
int& func() // compile warning
{
int a = 10;
return a;
}
int &b = func(); // ok, but segfault if try to use b.
int c = func(); // segfault immediately
#include <iostream>
using namespace std;
int x=15;
int main()
{
int x=10;
{
int x = 5;
cout<<::x; // should print 10;
}
return 0;
}
Is there any way to print x=10 without changing variable names, variable values and position of cout?
I assume this is an academic question (puzzle) because nobody should write code like that. In the same spirit, here's a way to make it print 10 instead of 15 without changing variable names, variable values and the position of cout:
#include <iostream>
using namespace std;
int x=15;
int main()
{
int x=10;
{
int x = 5;
#define x x-5
cout<<::x; // should print 10;
}
return 0;
}
Normally you should parenthesize such expressions in macros, like (x-5). In this case, that would be counterproductive :)
No you can't
An inner block, because it is a different block, can re-utilize a name existing in an outer scope to refer to a different entity; in this case, the name will refer to a different entity only within the inner block, hiding the entity it names outside.
Further information here: http://www.cplusplus.com/doc/tutorial/namespaces/
You cannot access x=10 in the inner block where you defined x=5. It can only see x=5 as x=10 is hidden at that point.
Ref: 3.3.7/1
A name can be hidden by an explicit declaration of that same name in a nested declarative region or derived class (10.2).
If you don't mind some horrible undefined behaviour, we could make assumptions about where local variables are stored on the stack. This works on my machineā¢ using g++ without any additional flags (although even -O1 breaks it):
#include <iostream>
using namespace std;
int x=15;
int main()
{
int x=10;
{
int x = 5;
cout<<*((&x) + 1); // should print 10;
}
return 0;
}
This is based on the assumption that local variables are placed on the call stack (or some other place) consecutively in main memory, in reverse order of declaration. It breaks in many cases, such as having a different order, having x=10 be placed in a register, or x=10 being optimized away entirely because it's unused.
#include <iostream>
using namespace std;
int x = 15;
int main()
{
int x = 10;
{
int x = 5;
}
cout << x; // should print 10;
return 0;
}
you should probably put cout<< to outside
#include <iostream>
using namespace std;
int i; //1 - global
class Test
{
public:
~Test()
{
i = 10;
}
};
int& foo()
{
int i = 3; //2 - local
Test ob;
return i;
}
int main()
{
cout << "i = " << foo() << endl; // output: i = 3
return 0;
}
I have queries for above code:
Variable i being local to foo, reference of which cannot be used (automatic variable). How does above code execute?
The Test object in foo function will be destroyed after return statement. How does foo function returns reference of 2 (i = 3)?
Variable i being local to foo, reference of which cannot be used (automatic variable). How does above code execute?
What you are doing is cause for undefined behavior. Unfortunately, seemingly sane behavior falls under undefined behavior too. A legendary answer on SO expounds on the subject.
The Test object in foo function will be destroyed after return statement. How does foo function returns reference of 2 (i = 3)?
The first statement is correct. However, that is not relevant to the issue of which i is returned from foo. foo returns a reference to the function local variable regardless of what Test does.
You always read and wrote the global i since you never declared local i or class member i in your code.
when you call foo() like
cout << "i = " << foo() << endl;
This block of code will execute
int& foo() {
i = 3; //2 - local
Test ob; /* object having local scope */
return i;
}/* when it goes out of this block.. destructor gets called */
above you are creating object ob. when it came out of scope, destructor ~Test() { } gets called automatically & in destructor you have i=10, so return i; will return i value which was there in destructor. so it prints i value as 10. Also i = 3; doesn't create new i it will consider global declared i.
updated code :
int& foo() {
int i = 3; /* here i is locally created */
Test ob;
return i; /* you can't return reference to local variable.. invokes UB */
}
Above code block will cause undefined behavior.
I saw this below example in Geek For Geeks.
#include<iostream>
using namespace std;
int &fun()
{
static int x = 10;
return x;
}
int main()
{
fun() = 30;
cout << fun();
return 0;
}
Answer is 30.
But i am unable to map, how this value is arrived at. Please help me as to how this piece of code works.
After some answers from experts, i got to know the value assigned to function is assigned to static variable x which is equivalent to fun()::x =30
Now, i tried a different piece of code.. where in i have 2 static variables inside the fun() and returning the second variable reference. Still the answer is 30. Is is because when, fun() is assigned, it assigns the value 30 to all the variables inside fun()?
Second piece of code is
#include<iostream>
using namespace std;
int &fun()
{
static int x = 10;
static int y =20;
return y;
}
int main()
{
fun() = 30;
cout << fun();
return 0;
}
fun returns a reference (int&) to the static variable x inside funs scope. So essentially the statement fun() = 30 is fun::x = 30. Note this is only safe because x is static.
function local static variables get initialized the first time into the function and persist until the end of the program. So when you call
fun() = 30;
You return a reference to that variable and then assign 30 to it. Since the variable is still alive it will keep that value. Then
cout << fun();
Is going to return the variable again. Since it was already initialized it will not reset its value and it returns 30 as that is what it was set to in the preceding line.
This question already has answers here:
Returning a reference to a local variable in C++
(3 answers)
Closed 9 years ago.
Here are two programs. Both of them have a function fun() whose return type is reference to an integer. Only the difference between two functions is that in one function x is declared as static int while in other it is not. The output to the first question is 10 and the output to the second question is 30. How?
Program 1:
#include<iostream>
using namespace std;
int &fun()
{
int x = 10;
return x;
}
int main()
{
fun() = 30;
cout << fun();
return 0;
}
Program 2:
#include<iostream>
using namespace std;
int &fun()
{
static int x = 10;
return x;
}
int main()
{
fun() = 30;
cout << fun();
return 0;
}
Program 1: you return a reference to a variable which ceases to exist as soon as the function returns, then store the value 30 to that non-existing variable, which may or may not crash your machine. Regardless, the following call to fun() reinitializes a local variable "x" and returns it.
Program 2: A static variable at function scope is kind of like a global variable that's only accessible to that function. You return a reference to that static (which still exists), and set its value. When you call the function again, the static still has the value you assigned to it.