10.6 – static and register storage class specifiers

by subbu on December 4, 2013

So far we have been discoursing auto and extern storage class specifiers. In this session we are going to discourse static and register storage class specifiers. The static storage class specifier is used in special situations like to improve the life of local variables along the program and restricting external variables and functions of other files (header files) from importing. Where as register storage class specifier is used to store the variable in CPU registers.

static storage class specifier in C language:

The keyword static is a storage class specifier used to declare local variables, external variables and functions on different purpose. We will discourse one by one with suitable demonstrating examples

Where do the static variables store?

static variables initialized by the program (may be local or external) are stored in read/write section of data segment and Un-initialized static variables are stored in BSS segment of memory. Un-initialized static variables are assigned with zeros by the operating system. Static variables are allocated on initiation of program execution that is even before starting the execution of program

Example:

#include<stdio.h>
int main()
{
 static int x=45;  /* stored in read/write section of data segment */
 static int y;     /* stored in BSS , initialized with zero*/
 printf("x=%d",x);
 printf("\ny=%d",y);
 return 0;
}

Output:
x=45
y=0

Static array is initialized with zero elements

Even an array can be defined with static storage class specifier. If the static array is initialized with a set of values then it is stored in data segment. If the static array is not initialized then it is stored in BSS segment and elements are initialized with zeros by operating system

#include<stdio.h>
int main()
{
 static int a[5];  /* un-initialized static array */
 int i;
 for(i=0;i<5;i++)
   printf("%5d",a[i]);
 return 0;
}

Output:
0        0        0        0        0

Static variable initializer must be a constants:

Static variables come into existence even before starting the execution of program. Hence, a static variable can’t be initialized with a variable.

#include<stdio.h>
int main()
{
 int y=10;
 static int x=y;   /* initializing with a variable */
 return 0;
}

Output:
error: initializer element is not constant
static int x=y;

static local variables

As we have discoursed, local variables come into existence on calling a function and disappear on completion of function execution. Local variables do not keep their values from one execution to another execution of function because they loose their life at the end of every execution.

By declaring local variables using the static storage class specifier, we can make the life of local variables permanent as long as the program executes. Hence, static local variables keep their values from one execution to another execution of function. The static initialization statement in a function executes only once during the first execution, skips from the second execution

Example:

#include<stdio.h>
void display(int);
int main()
{
 int i;
 for(i=1;i<=5;i++)
  display(i);
 return 0;
}
void display(int x)
{
 int a=100;             /* auto variable */
 static int b=100;     /* static variable */
 a=a+x;
 b=b+x;
 printf("\n%d\t%d",a,b);
}

Output:
101     101
102     103
103     106
104     110
105     115

Example explained:
Here in this example, a is an auto variable doesn’t keep its value for the next execution, a is assigned with 100 and added with formal argument x for every execution.
Where as, b is a static variable keep its value for the next execution as the life of static variable is permanent. Here b is assigned with 100 only for the first execution after that, the formal argument x is added to the existed value of a for every execution

Though the life of static local variable is extended along the program, accessibility (scope) is within the function only.

Example:

/* scope of static variables */
#include<stdio.h>
void display();
int main()
{
static int x=10;
display();
return 0;
}
void display()
{
printf("x=%d",x);
}

Output:
error: ‘x’ undeclared

Example explained:
Here x is a static local variable of main(), could not be accessed from the function display() because scope of x is limited to main() only.

static functions and external variables

As we discoursed in the previous session, external variables defined in one source file can be accessed from other source file by declaring them with extern storage class specifier.
We can always access the functions of one source file into another source file without any restriction
The static storage class specifier is used to restrict the access of external variables and functions of one source file into another source file

static external variables and functions

Here in file2.c an external variable y and a function process() are defined as non static entities, These may be accessed from any other source file
In the same file an external variable x and a function display() are defined as static entities, These may be used within the file but, can’t be accessed from other source files

Conclusion:

  • Static storage class specifier is used to improve the life of local variables
  • Scope of static local variables is with in the function only
  • Un-initialized static variables are stored in BSS section and initialized with zero, initialized static variables are stored in data segment.
  • Static variables come into existence even before starting the execution of program. Hence, a static variable can’t be initialized with a variable.
  • Static external variables, functions of one source file can’t be accessed into other source file

register storage class specifier:

Registers are the high speed memory available in CPU, which are used on other purpose.

Registers in CPU

The register storage class specifier instructs the compiler to store a variable in the registers. A value stored in the register can be accessed faster than one stored in the main memory.

Overall performance of a program can be improved by declaring heavily used variables like loop variables in registers.

register int i;
for(i=1;i<=80;i++)
{
 gotoxy(i,5);          /* sends the cursor to specified position */
 cprintf("%c",196); /* prints a graphic character - */
}

Here the above loop iterates for 80 times to print a horizontal line in 5th row, where i is accessed for 3 times in every iteration. Such variables can be defined as register variables to improve the overall performance of program.

Restrictions in using register storage class specifier:

Only local variables, block variables and formal argument can be defined as register variables.

/* to print horizontal line from (x1,y) to (x2,y)*/
void hline(register int x1,register int x2,int y)
{
 register int i;
 for(i=x1;i<=x2;i++)
 {
  gotoxy(i,y);
  cprintf("%c",196);
 }
}

External variables can’t be defined as register variables

register variables can’t have pointers and their address can’t be accessed (Will be covered later)
Certain types are not allowed. Say for example if CPU has 16bit registers then float and double type can’t be stored in registers
An array can’t be declared of register type

No guarantee:
Though we declare a variable with register storage class specifier, no guarantee that the variable would be stored in register because CPU has limited number of registers and they may be busy in doing some other job. In such case register variables behaves like auto variables.

Default value, scope, life and storage of register variables:

Default value: Garbage value
Scope: Within function as local variables
Life: Appears as control enters into the function and disappears as the function execution completed
Storage: In registers or in stack memory if registers are not free

Previous post:

Next post: