In the C programming language and its descendants, the term static variable has at least three separate meanings, each related to the semantics of C’s static keyword:
- Static global variables are declared as “static” at the top level of a source file. Such variables are not visible outside the source file (“file scope”), unlike variables declared as “extern”.
- Static local variables are declared inside a function, just like automatic local variables. They have the same scope as normal local variables, differing only in “storage duration”: whatever values the function puts into static local variables during one call will still be present when the function is called again.
- C++ has static member variables: in classes, member variables declared as “static” are class variables (as opposed to instance variables).
Static (C++)
The static keyword can be used to declare variables, functions, class data members and class functions.
By default, an object or variable that is defined outside all blocks has static duration and external linkage. Static duration means that the object or variable is allocated when the program starts and is deallocated when the program ends. External linkage means that the name of the variable is visible from outside the file in which the variable is declared. Conversely, internal linkage means that the name is not visible outside the file in which the variable is declared.
The static keyword can be used in the following situations.
- When you declare a variable or function at file scope (global and/or namespace scope), the static keyword specifies that the variable or function has internal linkage. When you declare a variable, the variable has static duration and the compiler initializes it to 0 unless you specify another value.
- When you declare a variable in a function, the static keyword specifies that the variable retains its state between calls to that function.
- When you declare 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. A static data member must be defined at file scope. An integral data member that you declare as conststatic can have an initializer.
- When you declare a member function in a class declaration, the static keyword specifies that the function is shared by all instances of the class. A static member function cannot access an instance member because the function does not have an implicit this pointer. To access an instance member, declare the function with a parameter that is an instance pointer or reference.
- You cannot declare the members of a union as static. However, a globally declared anonymous union must be explicitly declared static.
For more information, see auto, extern, and register.
Example
The following example shows the use of static in a class. The following example shows a local variable declared static in a member function. The static variable is available to the whole program; all instances of the type share the same copy of the static variable. static objects are placed in the data segment. They are initialized from values stored in the executable file, and therefore these values must be known at compile time. Initialization occurs only once. Values are maintained when the object is out of scope (e.g. between function calls), and it is safe to return a pointer or reference to them. Numeric values not explicitly initialized are set to 0.
The following example shows how a variable declared static in a function retains its state between calls to that function.
[cc lang=”cpp”]
// static1.cpp
// compile with: /EHsc
#include
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 );
}
[/cc]
Output:
nStatic is 0
nStatic is 1
nStatic is 3
nStatic is 6
nStatic is 10
[cc lang=”cpp”]
// static2.cpp
// compile with: /EHsc
#include
using namespace std;
class CMyClass
{
public:
static int m_i;
};
int CMyClass::m_i = 0;
CMyClass myObject1;
CMyClass myObject2;
int main()
{
cout << myObject1.m_i << endl;
cout << myObject2.m_i << endl;
myObject1.m_i = 1;
cout << myObject1.m_i << endl;
cout << myObject2.m_i << endl;
myObject2.m_i = 2;
cout << myObject1.m_i << endl;
cout << myObject2.m_i << endl;
CMyClass::m_i = 3;
cout << myObject1.m_i << endl;
cout << myObject2.m_i << endl;
}
[/cc]
Output:
0
1
1
2
2
3
3
Note
Assigning a value to a static local variable in a multithreaded application is not thread safe and we do not recommend it as a programming practice.
[cc lang=”cpp”]
// static3.cpp
// compile with: /EHsc
#include
using namespace std;
struct C {
void Test(int value) {
static int var = 0;
if (var == value)
cout << "var == value" << endl;
else
cout << "var != value" << endl;
var = value;
}
};
int main() {
C c1;
C c2;
c1.Test(100);
c2.Test(100);
}
[/cc]
var != value
var == value
static
+----------+
| |
| Heap | Allocated with new until deleted or program exits.
| |
+^^^^^^^^^^+
| Stack | Local objects, parameters, temporaries, function return addresses.
+----------+ +---------+
| Data | <-- | Data | Initial values for static and global objects.
+----------+ +---------+
| Code | <-- | Code | Executable machine instructions.
+----------+ +---------+ (Cannot be read or written by program.)
| Reserved | a.out on disk
| for OS |
| and other| Cannot be read or written by program, will cause segmentation
| programs | fault or general protection fault.
+----------+
Memory
[cc lang=”cpp”]
// Return by reference, f() is an alias for s, not a temporary copy
int& f() {
static int s=1; // Initialized only once
++s;
return s; // Safe to return by reference
}
int main() {
cout << f(); // 2
cout << f(); // 3
f()=5; // OK, s=5;
s=6; // Error, s is not in scope
}
[/cc]
[cc lang="cpp"]xxxx
bbb[/cc]