Static is a keyword in C (also in C++/Java) used as storage or linkage class specifier in C. Storage indicates how the variable is to be stored in memory and linkage specifies the linkage scope to be applied during the linking process. There are various storage classes in C namely – auto, register , const and static. There are linkage specifiers such as extern or static. In this blog, we are going to understand the various facets of the keyword “static”. For a beginner or a new programmer, this can get confusing. But, not after we decode this today ! So, let’s begin.
Usage Scenarios in C
Static can mean different things based on different contexts of usage. There are three types of usage that I can think of in C:
a. Static to declare a global variable in C
Suppose you have written a .c file with following :
// File : test.c
static int a; // global static variable
printf(“Static variable value is %d \n”, a); // can access static variable
In the example above declaring variable “a” static essentially restricts the usage of variable “a” to only inside the compilation unit / translation unit or the given “.c” file. No other file in your code can access this variable. So, in this scenario it is not really controlling the storage aspect but the scope of the variable. The scope is limited to the given file – meaning the functions inside this “.c” file alone can access or use the variable. Hence, static in this case essentially specifies “internal” linkage as opposed to using extern keyword usage – that specifies “External” linkage (note to self : we shall cover extern in the another blog).
b. Static to declare a variable inside a function in C
A variable declared “static” inside the scope of a function retains the value even after we exit the function – across multiple calls. By default variable inside function are treated as “auto” and are allocated on function stack ; but static is allocated in .DATA or .BSS section of memory.
To understand this scenario of usage consider the example below :
//Function with static variable
static int counter; // static local variable in func().
counter++; // increment counter to count function calls
printf(“Call counter is %d” , counter);
} // counter’s state is preserved even after we hit this point. (auto variables are lost)
// Example multiple calls to function func() above :
func(); // first call
} //after this call , the function prints “Call counter is 1”
func(); //second call
}//after this call , the function prints “Call counter is 2”
c. Static Function in C
The scope of these functions is limited to only the file they are contained in. We can think this as a way to attain “data encapsulation” in C as we see in OOP languages such as C++/Java.
Methods without static keyword are public while the ones with “static” keyword are “private” to the compilation unit / translation unit (the .c file).
Default Storage Specifier Rules
- Variables declared inside a function are considered “auto”
- Functions declared within a function are treated as “extern”
- Variables and functions declared outside a function are considered “static”, with external linkage
Static in c++
- In C++ it does not really specify a storage class. When a variable of a class is declared static (example variable named obj in the example below), it essentially means that all objects of that given class (exObj1 and exObj2 below) share same variable instance.
- If a function or member variable is declared static (example : variable named sample in the example code below), then it can be accessed without a class object – using just the class name (check usage in cout “Example::sample” below). This essentially means that the static member is associated only with class not the instance of the class or the “object”. It requires no instance of “this” operator.
- In case of inheritance, static “public” variables in the parent class are shared by the derived classes as well ; meaning a copy is not created. Whereas if they are declared “private” in parent class, then the derived classes cannot view or use the variable.
static int sample;
//constructor counts the objects created
static int obj; // static variable
cout<<“Object counter “<<obj<<endl;
Example exObj1 ; // when this is created constructor prints “Object counter 1”
Example exObj2; // when this is created constructor prints “Object counter 2”
cout<<“Accessing public static variable without object : “<<Example::sample<<endl; // accessing static member without object
Initializing and defining static
By default all static variables that are not initialized are set to zero. They are initialized at compile time. Static variables contained within a “.c file” limits the usage of variable to within one compilation unit/translation unit. But, if they are declared in a header file and this header is included in multiple .c files, then there will be multiple copies of the same variable (one copy per .c file). This kind of defeats the purpose of declaring it as “static” to limit the usage scope to specific translation unit. So, if you really want to limit the scope, just put it in the .c file and use.
Static variables in Memory
If you have read this previous blog on “Memory and Program“, you would know where the static variables go to in the memory when you use them in your program. If the static variable is initialized it goes into the .DATA section where as uninitialized static variables go to the .BSS (Block Start Segment).
That’s all for today folks ! Isn’t low level coding fun !? ;). Until next time – keep decoding ~!