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.
Related
I have read that static variables in c/c++ only initialised once.
But when i tried to experiment with it. I found that they can be initialised multiple times
#include <iostream>
#include <string>
using namespace std;
void demo(int value)
{
// static variable
static int count = 0;
count = value;
cout << count << " ";
}
int main()
{
for (int i=0; i<5; i++)
demo(i+1);
return 0;
}
In above code my initialised static variable count multiple times.
output is above code is : 1 2 3 4
is I am missing anything here?
count = value; is not initialization, it's assignment. Static variables can be assigned as many times as you wish.
static int count = 0; is initialization and that happens only once, no matter how many times you call demo.
Any variable can be initialized only once. Static is no different with respect to that. What is special about static local variables is that their value persists between function calls. And this of course only makes sense if the line that initialized it is only executed on the first function call. Consider this example:
#include <iostream>
#include <string>
using namespace std;
void demo()
{
// static variable
static int count = 0;
std::cout << ++count << " ";
}
int main()
{
for (int i=0; i<5; i++) demo();
return 0;
}
It prints
1 2 3 4 5
because the static in static int count = 0; means: only on the very first invocation of the function count is initialized with 0.
When a variable is declared as static, space for it gets allocated for the lifetime of the program.
Even if the function is called multiple times, space for the static variable is allocated only once and the value of variable in the previous call gets carried through the next function call.
count = value;-> This is assignment,and in this case static variables has same behavior like other data type (int for example).
#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 tried the following piece of code:
int& fun()
{
static int y = 20;
//y = 40;
return y;
}
int main()
{
fun() = 30;
cout << fun() <<endl;
return 0;
}
If, line y = 40 were uncommented, output of main is 40. Why doesn't the value of y change when it's assigned to 30 in main() ?
The variable y of the function func() has static storage duration:
3.7.1/1: All variables which do not have dynamic storage duration, do not have thread storage duration, and are not local have static
storage duration. The storage for these entities shall last for the
duration of the program
3.7.1/3: The keyword static can be used to declare a local variable with static storage duration.
The initialisation of such variables occurs only once. This means that the first time you use y its value is 20, afterwards it keeps the value that you store there in.
Case 1: assignment is commented out:
The statement fun() = 30; will store 30 in y. cout << fun() will use the reference to y without fun() changing it, so it will display 30.
Case 2: assignment is activated:
The statement fun() = 30; will store 30 in y. cout << fun() will use the reference to y but fun() will first set it to 40, so 40 will be displayed.
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.
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.