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).
Related
I am not able to understand the output of the below code:-
#include <iostream>
using namespace std;
template <typename T>
void fun(const T&x){
static int count = 0;
cout << "x = " << x << " count = " << count << endl;
++count;
return;
}
int main(){
fun(1);
fun('A');
fun(1.1);
fun(2.2);
return 0;
}
Output:-
x = 1 count = 0
x = A count = 0
x = 1.1 count = 0
x = 2.2 count = 1
If value of static variable count is being reassigned to 0 whenever the function is called, then why its coming 1 when the function is being called fourth time.
And another thing , can we not pass "T x" directly instead of "const T&x"?
When a template gets instantiated, with explicit or deduced template parameters, it's as if a completely new, discrete, class or function gets declared. In your case, this template ends up creating three functions:
void fun<int>(const int &x)
void fun<char>(const char &x)
void fun<double>(const double &x)
It's important to understand that each one of these is a separate, standalone function, with its own static count variable. Because it's static, it gets initialized once, and its value is preserved across function calls. That's how static variables work in functions.
The shown code calls the first two once, and the third one twice. Those are the results you are seeing (the 2nd call to the third function incremented the same static count again).
Templates in C++ aren't generic functions like they are in Java. They're more like cookie cutters that make a new type-specific function for each type used to instantiate them. Your code is basically equivalent to this:
#include <iostream>
using namespace std;
void fun_int(const int&x){
static int count = 0;
cout << "x = " << x << " count = " << count << endl;
++count;
return;
}
void fun_char(const char&x){
static int count = 0;
cout << "x = " << x << " count = " << count << endl;
++count;
return;
}
void fun_double(const double&x){
static int count = 0;
cout << "x = " << x << " count = " << count << endl;
++count;
return;
}
int main(){
fun_int(1);
fun_char('A');
fun_double(1.1);
fun_double(2.2);
return 0;
}
And now it's obvious that you don't just have one static variable, but rather three different ones in different functions that just happen to have the same name.
If value of static variable count is being reassigned to 0 whenever the function is called...
That's where you're wrong. A static variable with an initializer (irrespective of its scope) is set to the value of the initializer once and once only. For static variables declared globally (in file scope), that initialization will be at program start-up; for static data declared in functions (as yours are), that initialization is deferred to the first time the function's code is executed.
Your code defines three different overloads of fun, each of which has its own copy of the local count variable. When the overload with the double argument is called the second time, the count variable will not be reinitialized – just incremented.
From this Draft C++17 Standard:
6.8.3.2 Static initialization [basic.start.static]
1 Variables with static storage duration are initialized as a consequence of program
initiation. …
and, for locally-declared static variables, we have this:
9.7 Declaration statement [stmt.dcl]
…
4 Dynamic initialization of a block-scope variable
with static storage duration or thread storage
duration is performed the first time control passes through its
declaration; such a variable is considered initialized upon the completion of its initialization. …
#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;
class MyStaticClass{
public:
static int value;
MyStaticClass(){
value++;
}
~MyStaticClass(){}
};
int MyStaticClass::value;
void main(){
MyStaticClass::value = 0;
for (int i = 0; i<9; i++)
MyStaticClass *c = new MyStaticClass();
cout << MyStaticClass::value;
system("pause");
}
Please explain me why the result is 9, and when replace MyStaticClass *c = new MyStaticClass() with MyStaticClass c() the result changes to 0? Finally what is the meaning of int MyStaticClass::value;, why when i delete that line the compiler shows error? Thanks everyone!
The line int MyStaticClass::value; tells the compiler to reserve storage for the static variable value. If you don't do that then the linker will fail.
The result is 9 since the for loop body executes 9 times: you are creating 9 new instances of MyStaticClass (which isn't really a static class, it just has a static member). Note that you ought to delete all these objects else your program leaks memory.
MyStaticClass c(); declares a function prototype for a function c that takes no parameters and returns a MyStaticClass: it does not create an object. This is nicknamed the most vexing parse. Since no object is created, value stays at 0. It would have been a different matter had you written MyStaticClass c;
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.
I ran into a interesting issue today. Check out this pseudo-code:
void Loop()
{
static int x = 1;
printf("%d", x);
x++;
}
void main(void)
{
while(true)
{
Loop();
}
}
Even though x is static, why doesn't this code just print "1" every time? I am reinitializing x to 1 on every iteration before I print it. But for whatever reason, x increments as expected.
The initialization of a static variable only happens the first time. After that, the instance is shared across all calls to the function.
I am reinitializing x to 1 on every iteration
No, you're not: you're initializing it to 1, but it only gets initialized once.
static doesn't mean const.
From MSDN:
When modifying a variable, the static
keyword specifies that the variable
has static duration (it is allocated
when the program begins and
deallocated when the program ends) and
initializes it to 0 unless another
value is specified. When modifying a
variable or function at file scope,
the static keyword specifies that the
variable or function has internal
linkage (its name is not visible from
outside the file in which it is
declared).
A variable declared static in a
function retains its state between
calls to that function.
When modifying a data member in a
class declaration, the static keyword
specifies that one copy of the member
is shared by all instances of the
class. When modifying a member
function in a class declaration, the
static keyword specifies that the
function accesses only static members.
The value of static is retained between each function call, so for example (from MSDN again):
// static1.cpp
// compile with: /EHsc
#include <iostream>
using namespace std;
void showstat( int curr ) {
static int nStatic; // Value of nStatic is retained
// between each function call
nStatic += curr;
cout << "nStatic is " << nStatic << endl;
}
int main() {
for ( int i = 0; i < 5; i++ )
showstat( i );
}
In your example, x will increment as expected because the value is retained.
static in this context means that value should be retained between calls to the function. the initialization is done only once.