Storage Classes in C and C++

Storage Classes in C/C++ are used to describe which section of memory should be allocated to a variable. A storage class also defines the scope, visibility and life-time of a variable or function with in the program.

Basically there are four different storage classes in C and five in C++.

  1. auto
  2. register
  3. static
  4. extern
  5. mutable (only available in C++)

These storage classes in C/C++ tell the compiler how to store the subsequent variable and the general syntax for variable declaration that uses a storage class shown below.

storage_class data_type variable_name;

Types of Storage Classes in C/C++

Now, let us discuss these storage classes one by one.

Auto Storage Class

Variable defined inside a function or block with keyword ‘auto’ belongs to automatic storage class. All variables defined within a function or block are auto by default. Automatic Variables are local to the block which they are declared or defined get destroyed when program exit the block.

  • Storage : Memory
  • Default value : Garbage value.
  • Scope : Local to the block in which they are defined.
  • Life : Till the control remains within the block.
{
   int v1;
   auto int v2;
}

Above example defines two variables with in the same auto storage class.

Important features of auto storage class

  • Auto variables get memory allocated automatically at run-time.
  • The scope and visibility of the auto variables is limited to the block in which they are defined.
  • All local variable inside block or function are auto by default.
  • By default, auto variables are initialized with garbage value.
  • The memory assigned to auto variables cleared upon exiting the block.
//Example
#include <stdio.h>  

int main()
{                        // Block 1
int a; //auto by default
auto int a1;

printf("%d %d\n",a,a1); // printing default value of auto variables a, a1.

  {  // Block 2
    int i = 2;
    { // Block 3
       int j = 3;
      printf ( "\n%d ", j);
      printf("%d ",i);
    }
    printf ( "%d ", i);
   // printf("%d ",j);
  }

return 0;
}

Output:

84 8
3 2 2

In above example program you can see four variable (a, a1, i, j). Here, you may notice first two auto variables a (auto by default) and a1 which generated warning in compiler but print default garbage values.

And the next two variable i & j which are auto by default, variable i is declared and defined in block 2 which is also available to block 3 which already has a variable j as you can see from output 3 & 2 (j & i) got printed inside block 3.

In block 2, i got printed whereas j which was in block 3 got destroyed, if you try to print j we get compile time error. Similarly in block 1, i & j both got destroyed.

Register Storage Class

The register storage class is used to define variables that should be stored in a CPU register instead of RAM. This ‘register’ variables are local to the block in which they are defined and gets destroyed upon exit.

Only variables that are accessed frequently stored in registers and accessing variable from register are faster than memory. The unary ‘&’ operator cannot be applied to it as it does not have a memory location (for assigning address to another variable).

  • Storage: CPU registers.
  • Default value : garbage value.
  • Scope : Local to the block in which they are defined.
  • Life : Till the control remains within the block.

Syntax:

{
   register int variable;
}
//Example

int main() {  
   int a = 20;    
   int *q = &a;  
 printf("Value of a: %d\n", *q); 
 printf("Address of a: %u\n", q); 

register int i = 10;  
printf("Register var i = %d",i);
// Un - comment below code will generate compile time error 

/*    int *p = &i;  
 printf("Value of a: %d\n", *p); 
  printf("Address of a: %u\n", p); 
 */ 
return 0; 
}

Output:

Value of a: 20
Address of a: 6356744
Register var i = 10

Using keyword ‘register’ does not mean the variable get stored in CPU register, compiler check for space if available than only stored in register else stored as local/auto because the number of CPU registers are limited (14 in case of a micro-computer) busy doing some other task.

For example, the following declared variables treated as ‘auto’ and cannot be saved in register because CPU registers in a microcomputer are usually 16 bit registers and therefore cannot hold a float value or a double value, which require 4 and 8 bytes.

register float a;
register long b;
register double c;

Important feature of register storage class

  • Register variables cannot be de-reference as we cannot use & operator for the register variable.
  • Accessing register variables is faster than the automatic variables.

Static Storage Class

Static variables maintain their values between calls that can be used within function or file. Unlike global variables, static variables are not accessible outside their function in which they are defined.

The static storage class instructs the compiler to keep a local variable in alive during the life-time of the program.

  • Storage: Memory.
  • Default value : Zero.
  • Scope : Local to the block in which the variable defined.
  • Life : Maintain their values between calls Value during the life-time of the program.
//Example

void func();

int main()
{

func();
func();
func();

return 0;
}


void func(){
    static int i = 0;
    int a = 0;
    printf("i = %d\ta = %d\n",i,a);
    i++;
    a++;
}

Output:

i = 0   a = 0
i = 1   a = 0
i = 2   a = 0

When global variables are declared as static, there scope restricted to the file in which it is declared because it causes only one copy of that member to be shared by all the objects of its class.

Now follow below steps carefully to understand static global variable or function.

Static global variable

Step-1: Create two .c files on desktop. For example, file1.c,file2.c.

Step-2: Copy below code in files respectively.

//Copy this to file1.c
int a =10;  //global
//Copy this to file2.c
#include<stdio.h>

extern int a;
int main(void) 
{ 
printf("%d",a); 
  return 0;   
} 

Step-3: Now open CMD, change directory to desktop and type gcc -o <exe_file_name> file1.c file2.c.

C:\Users\CHAND>cd desktop

C:\Users\CHAND\Desktop>gcc -o example file1.c file2.c

Step-4: You can notice a exe file named example appear on desktop. Again in CMD type example.exe to see output.

C:\Users\CHAND\Desktop>example.exe
10

Step-5: Similarly repeat step 2 to 4 by replacing global variable in file1.c with static. Output will generate an error as “undefined reference to ‘a’“.

//Copy this to file1.c
static int a =10;  //global

Output:

C:\Users\CHAND\Desktop>gcc -o example file1.c file2.c
C:\Users\CHAND\AppData\Local\Temp\ccWIvQrl.o:file2.c:(.text+0xf): undefined reference to `a'
collect2.exe: error: ld returned 1 exit status

Important feature of Static

  • Same static variable can be declared many times but assigned value at only once.
  • Default value of the static integral variable is 0 otherwise null.

External Class

Keyword ‘extern’ used to instruct compiler that a variable declared has external linkage elsewhere in the program not within the same block where it is used. ‘extern’ give a reference of a global variable that is visible to all the program files.

When extern specifier is used, the variable does not get any memory allocated to that as it was already defined. Basically, extern variable is same as global variable initialized with a value where it is declared in order to be used elsewhere.

Suppose you have multiple files and you define a global variable or function, which may be used in other files, then extern will be used in another file to provide the reference of defined variable or function.

extern storage class commonly used only when there are two or more files sharing the same global variables or functions.

For example demo look at above illustration of static storage class (step-2).

Note: Functions are implicitly extern.

  • Storage: Memory.
  • Default initial value : Zero.
  • Scope : Global.
  • Life : As long as the program execution end.

Important feature of Extern

  • Extern variables are not allocated any memory.
  • The default value of external integral type is 0 otherwise null.
  • We can declare and defined extern variable at same time but can be modified any number of times.

Mutable Class (Only available in C++)

The mutable storage class is only available in C++ used on a class data member to make it modifiable even though an object is declared as const. We cannot declare static, const or reference members as mutable.

// Example

class Externcode
{
  public:
    Externcode() : x(1), y(2) { };  // using initilization list to assign values
    mutable int x;
    int y;
};

int main()
{
  const Externcode a;
  a.x = 35;
  // a.y = 45;
}

As of normally without keyword ‘mutable’ before ‘x’ compiler would have generated error because we mention keyword its modifiable. Similarly you can see output by un-commenting a.y with is not mutable.

Source: https://www.ibm.com/support/knowledgecenter/en/SSLTBW_2.3.0/com.ibm.zos.v2r3.cbclx01/mutable_storage_class_specifier.htm

Leave a Reply

Your email address will not be published. Required fields are marked *

%d bloggers like this: