Why does the following yield output as 30 ? while removing "static" from x gives 10 ?
#include<iostream>
using namespace std;
int &fun()
{
static int x = 10;
return x;
}
int main()
{
fun() = 30;
cout << fun();
return 0;
}
Why does the following yield output as 30 ? while removing "static" from x gives 10 ?
#include<iostream>
using namespace std;
int &fun()
{
static int x = 10;
return x;
}
int main()
{
fun() = 30;
cout << fun();
return 0;
}
using static, 'x' is not stored in the stack, it is stored in the .bss or in .data. So it keeps the value that you assign in the main and returns it when you call fun the second time (that's the meaning of that static).
If you remove static, x is allocated in the stack and when fun() returns it disappears. So the value of x is reinitialized to 10 each time you call fun().
Really, by removing the static, the first line of your main is meaningless because fun() returns a reference to nothing.
When x is static, it continues to exist after the function returns. So the assignment fun() = 30 reliably changes the value of x, and cout << fun() reliably prints the last assigned value of x (i.e. 30 in your code).
Without the static keyword, x has automatic storage duration so - as far as your program is concerned - starts to exist when the first statement inside fun() is reached AND ceases to exist when the function returns. The assignment fun() = 30 and the streaming cout << fun() therefore both exhibit undefined behaviour, since they each attempt to use (via a reference) a variable that has ceased to exist.
When behaviour is undefined, anything can happen (since the meaning of "undefined" in the C++ standard is that the C++ standard does not constrain what can happen). In your case, it just so happens a value of 10 (the result of the assignment inside fun()) is printed. That behaviour is not guaranteed - completely different results are also feasible (e.g. results change when using a different compiler, different optimisation settings, or even simply with phase of the moon).
Most compilers can be configured to give a warning when a function returns a reference or pointer to a variable with automatic storage duration. However, most modern compilers are configured by default so they do NOT give such a warning, so you will need to read documentation for your compiler to work out how to enable higher warning levels. If you do that you will find that your compiler will give a warning of some form about fun(), when the static keyword is removed.