Storage Classes in C++

Storage Classes

Storage classes will provide the following information to the compiler

  • Storage Area of a variable
  • Scope of a variable i.e in which block the variable is visible(accessible)
  • The lifetime of a variable: How long a variable is active i.e when it is erased from memory
  • Default value of a variable if it is not initialized
storage classes in C++

Auto

  • The Automatic storage variables are stored in the stack area of the data segment
  • By default, any type of variable is auto and the lifetime of auto variables is restricted within the body i.e how many times we are calling the function and those many times that auto variables are constructed and destroyed
  • The scope of the auto variable is restricted within the body i.e you can access it only within the block or function is declared.

Example:

Run
#include <iostream>
using namespace std;

void demo()
{
    auto a = 10; //auto variable
    
    // below is also auto as variables are have auto storage type by default
    // int a = 10; // auto variable
    
    ++a;

    cout << "a is " << a << "\n";
}
int main()
{
    demo(); //creates 'a' and destroys that memory
    demo(); //creates a new 'a' and destroys that memory
}

O/P

a is 11
a is 11
  • In the above example upon calling demo(), it created a variable ‘a’ and destroyed it after executing the function at the end. Now if we call the function demo() again it creates a new variable ‘a’ again and destroys it at the end of the function
  • Hence how many times you call the function that many times auto variables are created and destroyed.

Register

  • They are stored in CPU registers and can be easily accessed because the access speed from registers is faster than the normal memory
  • When we are accessing a variable what the program most frequently then declares that variable is registered so that program execution speed improves because access time of variable comes down

Example

Run
#include <iostream>
using namespace std;

int main() 
{ 
    int n; 
    register int fact = 1; 
    
    // fact variable is stored in cpu register not in stack 
    // reason to register variables is that 
    // access speed of registers is faster than the normal memory
    
    cout << " Enter a number:"; 
    cin >> n; 
    
    for(int i = 1;i <= n; i++) 
    { 
        fact = fact * i; 
        
    } 
    
    cout << "\nFactorial of "<< n << " is: " << fact;
    
    return 0;
}

O/P

Enter a number:5 
Factorial of 5 is 120
In the above program, the compiler needs to access the fact variable n number of times in each iteration. Hence if you declare that variable as a register it is stored in a CPU register and access time gets reduced which improves program execution speed

Limitations

  • CPU registers are very limited you cannot create a large number of variables as a register
  • Not all variables declared as registers will get stored in CPU registers it depends on various restrictions on implementation and hardware

Static

  • Static storage class variables are created only once and are active throughout the program
  • Static storage class variables are stored in the static area of the data segment
Example program to show the purpose of static variables
Run
#include <iostream>
using namespace std;

void demo()
{
    auto a = 5; //non_static variable
    static int x = 5;//static variable
    ++a;
    ++x;
	
    cout << "a is " << a << "\t" << " x is " << x << "\n";

}

int main()
{
    demo();
    demo();
    demo();
	
    return 0;
}

Output

a is 6 x is 6
a is 6 x is 7
a is 6 x is 8
  • In the above example you can clearly understand the difference between static and non-static variables .’ a’ is not static and each time you call demo()   variable ‘a’ created and destroyed
  • ‘x’ is a static variable you may call demo() any number of times but  allocated memory for variable ‘x’ only once, from the all second call all changes will be made in existing variable memory only

Extern

  • Extern acstorage class allows you to access the global variables declared in one source file another source file
  • They are visible throughout the program and its lifetime is the same as a lifetime of the program where it is declared
  • As it is having Global scope it can be accessible to all functions in the program

Example

File: add.cpp
Run
int test=10; // assigning value to test
void add(int n)
{
  test=test+n;
}
File: main.cpp
Run
extern int test; // declaring test
int main()
{
  cout<<test<<endl;
  add(5);
  cout<<test<<endl;
  return 0;
}

O/P

10 
15

Note:run main.cpp program

  • A variable test is declared as external in main.cpp. It is a global variable and it is assigned to 15 in add.cpp. It can be accessed in both files.
  • The function add() adds the value of the test with the parameter passed to it while invoking it.
  • The program performs the addition and changes the global variable test to 15.

Mutable(Exclusively in C++)

Definition: Mutable data members can be modified even if they are the part of the objects that are declared as constant

Whenever make an object constant the data members of that object cannot be modified during the program execution, but If we still want to change some of the data members of a constant object, we need to make the data member of the constant object as mutable  so that it can be modified

Run
#include <iostream>
using namespace std;

class cube
{
    mutable int a; //can be changed
    int b;
    public:
    
    cube( int x, int y ){
        a = x;
        b = y;
    }

    void value() const{
        a = a*a*a;
    }

    void show() const{
        cout << "a : " << a << endl;
        cout << "b : " << b << endl;
    }
};

int main()
{
    const cube s( 3, 6 );// const object still a is changed
    cout << "Values of a and b" << endl;
    
    s.show();
    s.value();
    
    cout << "New values of a and b" << endl;
    
    s.show();

    return 0;
}

O/P

Values of a and b
a:3
b:6
New Values of a and b
a:27
b:6
In above example 'a' and 'b' are members  created by constant objects hence they cannot be modified but here 'a' is mutable hence modifications are allowed on 'a', whereas 'b' is nonmutable and belongs to the constant object so it cannot be changed