bool SomeClass::Function( bool thankYou = true )
{
static bool justAbool = false;
// Do something with justAbool;
...
}
I have searched around but I can't find anything about this except globals vars or member functions itself.
What does the above do, i.e. what happens, does justAbool keep its value after leaving the scope? Or does it 'remember' the value when it re-enters the scope?
The variable justAbool is initialized to false only once and it is initialized before the function is entered. The value will be remembered after leaving the scope of the function. It is important to note that the value will also be shared by all instances of SomeClass just like a static member variable. The variable justAbool will not be re-initialized if you create a new instance of your class and then call the function again.
static when applied to a local variable gives that variable static storage duration. This means that the justAbool's lifetime lasts to the end of the program rather than to the end of the invocation of the function. It's scope stays the same, it can only be accessed by name in the function, after the declaration appears.
justAbool will be initialized (using the supplied initializer = false) the first time that the function is called. Thereafter it will retain its previous value, it will not be reinitialized when the function is called again.
Here are some fuller details about storage duration and lifetimes, with references to the standard.
If an object has static storage duration, it means that the storage for the object lasts for the duration of the program (beginning to end). (3.7.1 [basic.stc.static])
As a bool is a type without a non-trivial constructor, its lifetime mirrors that of its storage, i.e. it lives from the beginning to the end of the program. (3.8 [basic.life])
All objects with static storage duration (including local objects) are zero-initialized before any other initialization. (6.7/4 [stmt.decl]) [For local objects with an initializer this is fairly academic because there is no way to read their value before their declaration is reached.]
Local objects of POD type with static storage duration initialized with constant-expressions are initialized before their block is entered, otherwise local objects with static storage duration are initialized when control passes through their declaration. (6.7/4 again)
An implementation is permitter, but not required, to perform early initialization in some situations.
The above function does what it does in the comment // Do something with justAbool;.
On a serious note, yes, the static variable (in this case justAbool) inside a function retains it's value even after returning from the function. It gets initialized ONLY ONCE. And each successive calls uses it as if it's a global variable. Its life-time is equal to the end of the program.
int f()
{
static int v = 0;
return ++v;
}
int main()
{
cout << f() << endl;
cout << f() << endl;
cout << f() << endl;
cout << f() << endl;
}
Output:
1
2
3
4
Online Demo : http://www.ideone.com/rvgB5
The justAbool is actually a regular static variable - it exists from the start of the program and is initialized only once. The special thing is that is is known only in this function - if you try and use it outside the function the compiler won't know what it is.
justAbool keeps its value after leaving the scope. What else did you want this code to do exactly?
function level static local variable, the initialization depends on variable types:
POD: initialized before main()
non-POD: initialized the first time, the line in the function is executed.
Related
If a variable is declared as static in a function's scope it is only initialized once and retains its value between function calls. What exactly is its lifetime? When do its constructor and destructor get called?
void foo()
{
static string plonk = "When will I die?";
}
The lifetime of function static variables begins the first time[0] the program flow encounters the declaration and it ends at program termination. This means that the run-time must perform some book keeping in order to destruct it only if it was actually constructed.
Additionally, since the standard says that the destructors of static objects must run in the reverse order of the completion of their construction[1], and the order of construction may depend on the specific program run, the order of construction must be taken into account.
Example
struct emitter {
string str;
emitter(const string& s) : str(s) { cout << "Created " << str << endl; }
~emitter() { cout << "Destroyed " << str << endl; }
};
void foo(bool skip_first)
{
if (!skip_first)
static emitter a("in if");
static emitter b("in foo");
}
int main(int argc, char*[])
{
foo(argc != 2);
if (argc == 3)
foo(false);
}
Output:
C:>sample.exe
Created in foo
Destroyed in foo
C:>sample.exe 1
Created in if
Created in foo
Destroyed in foo
Destroyed in if
C:>sample.exe 1 2
Created in foo
Created in if
Destroyed in if
Destroyed in foo
[0] Since C++98[2] has no reference to multiple threads how this will be behave in a multi-threaded environment is unspecified, and can be problematic as Roddy mentions.
[1] C++98 section 3.6.3.1 [basic.start.term]
[2] In C++11 statics are initialized in a thread safe way, this is also known as Magic Statics.
Motti is right about the order, but there are some other things to consider:
Compilers typically use a hidden flag variable to indicate if the local statics have already been initialized, and this flag is checked on every entry to the function. Obviously this is a small performance hit, but what's more of a concern is that this flag is not guaranteed to be thread-safe.
If you have a local static as above, and foo is called from multiple threads, you may have race conditions causing plonk to be initialized incorrectly or even multiple times. Also, in this case plonk may get destructed by a different thread than the one which constructed it.
Despite what the standard says, I'd be very wary of the actual order of local static destruction, because it's possible that you may unwittingly rely on a static being still valid after it's been destructed, and this is really difficult to track down.
The existing explanations aren't really complete without the actual rule from the Standard, found in 6.7:
The zero-initialization of all block-scope variables with static storage duration or thread storage duration is performed before any other initialization takes place. Constant initialization of a block-scope entity with static storage duration, if applicable, is performed before its block is first entered. An implementation is permitted to perform early initialization of other block-scope variables with static or thread storage duration under the same conditions that an implementation is permitted to statically initialize a variable with static or thread storage duration in namespace scope. Otherwise such a variable is initialized the first time control passes through its declaration; such a variable is considered initialized upon the completion of its initialization. If the initialization exits by throwing an exception, the initialization
is not complete, so it will be tried again the next time control enters the declaration. If control enters the declaration concurrently while the variable is being initialized, the concurrent execution shall wait for completion of the initialization. If control re-enters the declaration recursively while the variable is being initialized, the behavior is undefined.
FWIW, Codegear C++Builder doesn't destruct in the expected order according to the standard.
C:\> sample.exe 1 2
Created in foo
Created in if
Destroyed in foo
Destroyed in if
... which is another reason not to rely on the destruction order!
The Static variables are come into play once the program execution starts and it remain available till the program execution ends.
The Static variables are created in the Data Segment of the Memory.
If a variable is declared as static in a function's scope it is only initialized once and retains its value between function calls. What exactly is its lifetime? When do its constructor and destructor get called?
void foo()
{
static string plonk = "When will I die?";
}
The lifetime of function static variables begins the first time[0] the program flow encounters the declaration and it ends at program termination. This means that the run-time must perform some book keeping in order to destruct it only if it was actually constructed.
Additionally, since the standard says that the destructors of static objects must run in the reverse order of the completion of their construction[1], and the order of construction may depend on the specific program run, the order of construction must be taken into account.
Example
struct emitter {
string str;
emitter(const string& s) : str(s) { cout << "Created " << str << endl; }
~emitter() { cout << "Destroyed " << str << endl; }
};
void foo(bool skip_first)
{
if (!skip_first)
static emitter a("in if");
static emitter b("in foo");
}
int main(int argc, char*[])
{
foo(argc != 2);
if (argc == 3)
foo(false);
}
Output:
C:>sample.exe
Created in foo
Destroyed in foo
C:>sample.exe 1
Created in if
Created in foo
Destroyed in foo
Destroyed in if
C:>sample.exe 1 2
Created in foo
Created in if
Destroyed in if
Destroyed in foo
[0] Since C++98[2] has no reference to multiple threads how this will be behave in a multi-threaded environment is unspecified, and can be problematic as Roddy mentions.
[1] C++98 section 3.6.3.1 [basic.start.term]
[2] In C++11 statics are initialized in a thread safe way, this is also known as Magic Statics.
Motti is right about the order, but there are some other things to consider:
Compilers typically use a hidden flag variable to indicate if the local statics have already been initialized, and this flag is checked on every entry to the function. Obviously this is a small performance hit, but what's more of a concern is that this flag is not guaranteed to be thread-safe.
If you have a local static as above, and foo is called from multiple threads, you may have race conditions causing plonk to be initialized incorrectly or even multiple times. Also, in this case plonk may get destructed by a different thread than the one which constructed it.
Despite what the standard says, I'd be very wary of the actual order of local static destruction, because it's possible that you may unwittingly rely on a static being still valid after it's been destructed, and this is really difficult to track down.
The existing explanations aren't really complete without the actual rule from the Standard, found in 6.7:
The zero-initialization of all block-scope variables with static storage duration or thread storage duration is performed before any other initialization takes place. Constant initialization of a block-scope entity with static storage duration, if applicable, is performed before its block is first entered. An implementation is permitted to perform early initialization of other block-scope variables with static or thread storage duration under the same conditions that an implementation is permitted to statically initialize a variable with static or thread storage duration in namespace scope. Otherwise such a variable is initialized the first time control passes through its declaration; such a variable is considered initialized upon the completion of its initialization. If the initialization exits by throwing an exception, the initialization
is not complete, so it will be tried again the next time control enters the declaration. If control enters the declaration concurrently while the variable is being initialized, the concurrent execution shall wait for completion of the initialization. If control re-enters the declaration recursively while the variable is being initialized, the behavior is undefined.
FWIW, Codegear C++Builder doesn't destruct in the expected order according to the standard.
C:\> sample.exe 1 2
Created in foo
Created in if
Destroyed in foo
Destroyed in if
... which is another reason not to rely on the destruction order!
The Static variables are come into play once the program execution starts and it remain available till the program execution ends.
The Static variables are created in the Data Segment of the Memory.
Given C++ Primer's description of local static objects:
It can be useful to have a local variable whose lifetime continues across calls to the function. We obtain such objects by defining a local variable as static. Each local static object is initialized before the first time execution passes through the object’s definition. Local statics are not destroyed when a function ends; they are destroyed when the program terminates.
I was surprised to find that the following code compiled fine with sensible output:
#include <iostream>
using namespace std;
void test(int x){
static int y = x;
cout << y;
}
int main(){
test(2);
test(5);
test(6);
}
By such a description it would seem that initializing using a function argument would be impossible or not make much sense, how could it initialize y before execution passes through the function, how would it know what x is yet? Is this an oversimplification by C++ Primer or might my program be in a compiler-undetectable error?
For those wondering why I might be trying to initialise a static variable with an argument, I was trying to create a function that used default_random_engine to return a random integer in the provided range every time it was called (and so required static so the objects weren't destroyed) as part of another exercise for C++ Primer:
unsigned randomUns(unsigned minV, unsigned maxV, default_random_engine::result_type seed = 0){
static default_random_engine e(seed);
static uniform_int_distribution<unsigned> u(minV, maxV);
return u(e);
}
The word "before" is poorly chosen by your source. The C++ standard describes the initialization of block-scope variables with static storage duration like this [stmt.dcl]/4:
Dynamic initialization of a block-scope variable with static storage duration (3.7.1) or thread storage duration (3.7.2) is performed the first time control passes through its declaration; such a variable is considered
initialized upon the completion of its initialization. If the initialization exits by throwing an exception, the initialization is not complete, so it will be tried again the next time control enters the declaration. If control
enters the declaration concurrently while the variable is being initialized, the concurrent execution shall wait for completion of the initialization.
So your variable y is initialize the first time you call test.
I need to know the difference,am beginner.
void func()
{
static int static_var=1;
int non_static_var=1;
static_var++;
non_static_var++;
cout<<"Static="<<static_var;
cout<<"NonStatic="<<non_static_var;
}
void main()
{
clrscr();
int i;
for (i=0;i<5;i++)
{
func();
}
getch();
}
The above gives output as:
Static=2
Nonstatic=2
Static=3
Nonstatic=2
Static=4
Nonstatic=2
Static=5
Nonstatic=2
Static=6
Nonstatic=2
Static variable retains its value while non-static or dynamic variable is initialized to '1' every time the function is called. Hope that helps.
A static variable is a single memory location associated with the class.
A non-static variable (that is a member of a class) represents a different memory location for each instance of the class.
Static variables can be initialized only once and assign to 0 when an object is created.
static namespace scope variables have internal linkage, while non-static namespace scope variables have external linkage by default! Details: a const namespace scope variable has internal linkage by default. That linkage can by changed by keyword extern.
static variables in a class is associated with the class, that means, all instances of the class have the same instances of the static variables; they’re like a global variables that every instance of the same class has access to.
non-static variables in a class are instance members, that is, every instance of the class will have its own instances of the non-static variables.
a static data member of a class has external linkage if the name of the class has external linkage. [$3.5/5]
a static variable inside a function retains its value even after returning from the function.
That is, its lifetime is equal to the lifetime of the program itself. This is demonstrated in Mahesh's answer.
Main difference in static and normal variable is in their lifetime, for example scope and lifetime of local variable is within the function-loop in which it is declared, but scope of static variable is same as local variable means it will be accessed within which function it is declared(if not defined globally), but lifetime is through the program. So memory allocation depends on the lifetime, so as static variable will not die till program terminates so no new memory allocated, so fixed memory address allocated to static variables and value in that address will be overwritten every time we change the value of variable, while for normal variable as soon as you will go out of scope, variable will die(means memory will be freed for that variable) and when you will define variable again new memory address will be assigned, new value will be stored in address and no concept of overwrite(when we go out of scope).
Static variable retains its value during function calls/loops but local variable doesn't;
#include <iostream>
void foo()
{
for( int i=0; i<5; ++i )
{
static int staticVariable = 0;
int local = 0;
++local;
++staticVariable;
cout << local << "\t" << staticVariable << "\n";
}
}
int main()
{
foo();
return 0;
}
Results:
1 1
1 2
1 3
1 4
1 5
When a static variable is a member of a class, each instance share the static variable. Each instance doesn't have it's own copy.
class foo
{
public:
static int staticVariable;
};
int foo::staticVariable = 0;
foo obj1, obj2 ; // Both the instances share the static variable.
Static members are members that are single shared member common to all the objects created for a particular class but non-static are not so.
Memory allocation is done only once and not every time an object is created like non-static members.
Only one copy of static data member will exist irrespective of the number of objects created.
Static member functions can access only static member variables while a non-static member can be accessed by both static and non-static member functions.
Static members are efficient when single copy of data is enough.
Apart from differences in all these answers, there is one more difference between static and local variables:
local variables are stored on the stack, while static variables are stored in the data section of a process memory.
suppose class A has static variable x... and not static variable p
now if you create hundred instance of class A (i.e A a;) x would be shared among this hundred instance... but there would be hundred copies of p... one copy of p per instance of A
There are three different types of "static" variables.
Outside functions and classes, a "normal" variable would be a global variable. A static variable outside a function is not global, but local to the .cpp file in which it's defined. (Don't define this type of static variables in header files!)
Inside a function, a normal variable is destroyed when the function exits. A static variable in a function retains its value even after the function exits.
Inside a class, a normal member belongs to an object. A static member is shared between all objects of that type, and even exists before any object of that class is created.
The main Difference between "Static Variable" and the "Local variable"
The memory allocation of the local variable is deallocated if their work is done,
on other hand, the Memory allocation for the static variable remains the same
until the program terminates or overwritten by the another value of the program.
For example, Suppose You are using a recursion problem, If you are using the local variable during the recursive call, the memory allocation of the Local variable is removed, during the returning of the function.
On the other hand, if you are using the static variable, the memory allocation of that variable will remain until the program ends. It shall intact its values during the returning of the function, or can be overwritten by the programe.
If a variable is declared as static in a function's scope it is only initialized once and retains its value between function calls. What exactly is its lifetime? When do its constructor and destructor get called?
void foo()
{
static string plonk = "When will I die?";
}
The lifetime of function static variables begins the first time[0] the program flow encounters the declaration and it ends at program termination. This means that the run-time must perform some book keeping in order to destruct it only if it was actually constructed.
Additionally, since the standard says that the destructors of static objects must run in the reverse order of the completion of their construction[1], and the order of construction may depend on the specific program run, the order of construction must be taken into account.
Example
struct emitter {
string str;
emitter(const string& s) : str(s) { cout << "Created " << str << endl; }
~emitter() { cout << "Destroyed " << str << endl; }
};
void foo(bool skip_first)
{
if (!skip_first)
static emitter a("in if");
static emitter b("in foo");
}
int main(int argc, char*[])
{
foo(argc != 2);
if (argc == 3)
foo(false);
}
Output:
C:>sample.exe
Created in foo
Destroyed in foo
C:>sample.exe 1
Created in if
Created in foo
Destroyed in foo
Destroyed in if
C:>sample.exe 1 2
Created in foo
Created in if
Destroyed in if
Destroyed in foo
[0] Since C++98[2] has no reference to multiple threads how this will be behave in a multi-threaded environment is unspecified, and can be problematic as Roddy mentions.
[1] C++98 section 3.6.3.1 [basic.start.term]
[2] In C++11 statics are initialized in a thread safe way, this is also known as Magic Statics.
Motti is right about the order, but there are some other things to consider:
Compilers typically use a hidden flag variable to indicate if the local statics have already been initialized, and this flag is checked on every entry to the function. Obviously this is a small performance hit, but what's more of a concern is that this flag is not guaranteed to be thread-safe.
If you have a local static as above, and foo is called from multiple threads, you may have race conditions causing plonk to be initialized incorrectly or even multiple times. Also, in this case plonk may get destructed by a different thread than the one which constructed it.
Despite what the standard says, I'd be very wary of the actual order of local static destruction, because it's possible that you may unwittingly rely on a static being still valid after it's been destructed, and this is really difficult to track down.
The existing explanations aren't really complete without the actual rule from the Standard, found in 6.7:
The zero-initialization of all block-scope variables with static storage duration or thread storage duration is performed before any other initialization takes place. Constant initialization of a block-scope entity with static storage duration, if applicable, is performed before its block is first entered. An implementation is permitted to perform early initialization of other block-scope variables with static or thread storage duration under the same conditions that an implementation is permitted to statically initialize a variable with static or thread storage duration in namespace scope. Otherwise such a variable is initialized the first time control passes through its declaration; such a variable is considered initialized upon the completion of its initialization. If the initialization exits by throwing an exception, the initialization
is not complete, so it will be tried again the next time control enters the declaration. If control enters the declaration concurrently while the variable is being initialized, the concurrent execution shall wait for completion of the initialization. If control re-enters the declaration recursively while the variable is being initialized, the behavior is undefined.
FWIW, Codegear C++Builder doesn't destruct in the expected order according to the standard.
C:\> sample.exe 1 2
Created in foo
Created in if
Destroyed in foo
Destroyed in if
... which is another reason not to rely on the destruction order!
The Static variables are come into play once the program execution starts and it remain available till the program execution ends.
The Static variables are created in the Data Segment of the Memory.