What is a Storage Class in C?
In C programming, a storage class is a specifier that determines four key
characteristics of a variable or a function:
1. Scope (or Visibility): Where in the program can the variable be
accessed? Is it available only within a function, a specific block of
code, a single file, or the entire program?
2. Lifetime (or Extent): How long does the variable exist in memory
during the program's execution? Does it get created and destroyed
every time a function is called, or does it persist for the entire
duration of the program?
3. Storage Location: Where is the variable stored in memory? The
primary locations are the stack, the data/BSS segment(The term BSS
stands for "Block Started by Symbol." This segment stores global and static
variables that are uninitialized or initialized to zero.), or CPU registers.
4. Default Initial Value: If you don't explicitly assign a value to the
variable when you declare it, what value will it hold by default? Will
it be zero, or will it contain an unpredictable "garbage" value?
C provides four storage class specifiers:
• auto
• extern
• static
• register
1. The auto Storage Class
The auto storage class is the default for all local variables declared inside
a function or a block. The auto keyword explicitly declares a variable
with automatic storage duration.
• Scope: Block-level. The variable is only accessible within the block
({...}) in which it is defined.
• Lifetime: Session-level. The variable is created when the block is
entered and destroyed when the block is exited. Its value is not
retained between function calls.
• Storage Location: Stack. The region of memory that is fast and
automatically managed.
• Default Initial Value: Garbage value (an unpredictable value left
over in that memory location).
Key Point: Since it's the default for local variables, you almost never see
the auto keyword used in modern C code.
Declaring int i; inside a function is the same as declaring auto int i;.
This program demonstrates that the auto variable my_var is re-initialized
every time the function is called.
#include <stdio.h>
// This function demonstrates the 'auto' storage class.
void demonstrate_auto()
{
// 'my_var' is an automatic local variable.
// The 'auto' keyword is optional here, as it's the default.
auto int my_var = 1;
printf("Inside demonstrate_auto(), my_var = %d\n", my_var);
// Increment the variable.
my_var++;
printf("After increment, my_var = %d\n", my_var);
// When the function exits, 'my_var' is destroyed.
}
int main() {
printf("Calling demonstrate_auto() for the first time:\n");
demonstrate_auto();
printf("\nCalling demonstrate_auto() for the second time:\n");
demonstrate_auto(); // 'my_var' is created again from scratch and
initialized to 1.
return 0;
}
Expected Output:
Calling demonstrate_auto() for the first time:
Inside demonstrate_auto(), my_var = 1
After increment, my_var = 2
Calling demonstrate_auto() for the second time:
Inside demonstrate_auto(), my_var = 1
After increment, my_var = 2
2. The extern Storage Class
The extern storage class is used to declare a global variable that is defined
in another file. It essentially tells the compiler, "This variable exists, but
its memory is allocated somewhere else. Just know its type and name for
now, and the linker will connect them later."
• Scope: Global (multi-file). Accessible from any file that includes
its extern declaration.
• Lifetime: Program-level. It exists for the entire duration of the
program's execution.
• Storage Location: Data Segment (or BSS Segment if uninitialized).
• Default Initial Value: Zero.
Key Concepts:
• Definition: Allocating memory for the variable (e.g., int
global_count = 50;). A variable can only be defined once.
• Declaration: Simply telling the compiler about the variable's type
and name without allocating memory (e.g., extern int
global_count;). A variable can be declared multiple times.
#include <stdio.h>
int num = 50; // global variable
int main()
{
extern int num; // already declared above
printf("Extern variable: %d\n", num);
return 0;
}
Expected Output:
Extern variable: 50
Next way to demonstrate extern, we need two separate source files.
File 1: support.c
This file defines the global variable.
#include <stdio.h>
// DEFINITION of the global variable.
// Memory is allocated for it here.
int global_var = 100;
void print_global_from_support() {
printf("From support.c: global_var = %d\n", global_var);
}
File 2: main.c
This file uses the extern keyword to declare that it wants to use the
variable defined in support.c.
#include <stdio.h>
// DECLARATION of the global variable defined in another file.
// The 'extern' keyword tells the compiler that 'global_var' exists
// but is defined elsewhere. No memory is allocated here.
extern int global_var;
// We can also declare functions from other files.
extern void print_global_from_support();
int main() {
printf("From main.c: Accessing global_var, value = %d\n",
global_var);
// We can also modify the global variable from here.
global_var = 250;
printf("From main.c: Modified global_var, new value = %d\n",
global_var);
// Call the function from the other file to see the change.
print_global_from_support();
return 0;
}
How to Compile and Run:
You need to compile both files together.
gcc main.c support.c -o program
./program
Expected Output:
From main.c: Accessing global_var, value = 100
From main.c: Modified global_var, new value = 250
From support.c: global_var = 250
3. The static Storage Class
The static keyword has two distinct uses depending on where it's applied.
Use 1: Static Local Variable (inside a function)
When used on a local variable, static changes its lifetime from session-
level to program-level. The variable is initialized only once and retains its
value between function calls.
• Scope: Block-level (still only visible inside the function).
• Lifetime: Program-level (continues for the entire program).
• Storage Location: Data/BSS Segment.
• Default Initial Value: Zero.
Use 2: Static Global Variable (outside a function)
When used on a global variable, static restricts its scope to the current file
only. It cannot be accessed from other files using extern. This is useful
for creating private helper variables or functions within a module.
• Scope: File-level.
• Lifetime: Program-level.
• Storage Location: Data/BSS Segment.
• Default Initial Value: Zero.
This program demonstrates a static local variable that acts as a determined
counter.
#include <stdio.h>
// A static global variable. It is only visible within this file
(static_example.c).
// Another file trying to use 'extern int file_scope_var;' would result in a
linker error.
static int file_scope_var = 50;
// This function uses a static local variable.
void counter_function()
{
// 'static_count' is initialized ONLY ONCE when the program starts.
// It retains its value between calls.
static int static_count = 0;
// 'auto_count' is a regular auto variable for comparison.
// It is initialized to 0 on every function call.
int auto_count = 0;
static_count++;
auto_count++;
printf("Static Counter: %d, Auto Counter: %d\n", static_count,
auto_count);
}
int main()
{
printf("Calling counter_function multiple times:\n");
counter_function();
counter_function();
counter_function();
printf("\nThe file-scope static variable is: %d\n", file_scope_var);
return 0;
}
Expected Output:
Calling counter_function multiple times:
Static Counter: 1, Auto Counter: 1
Static Counter: 2, Auto Counter: 1
Static Counter: 3, Auto Counter: 1
The file-scope static variable is: 50
4. The register Storage Class
The register keyword is a hint or request to the compiler to store a
variable in a CPU register instead of main memory (RAM). Accessing
CPU registers is much faster than accessing RAM.
• Scope: Block-level.
• Lifetime: Session-level.
• Storage Location: CPU Register (if the compiler honors the
request) or Stack (if it doesn't).
• Default Initial Value: Garbage value.
Important Limitations:
• It's only a suggestion. Modern compilers are extremely good at
optimization and may ignore the register keyword. They often make
better decisions about which variables to place in registers.
• You cannot take the address of a register variable using
the & operator. This is because registers don't have a memory
address in the same way RAM does.
This program shows how to declare a register variable and highlights the
fact that you cannot take its address.
#include <stdio.h>
int main()
{
// Requesting the compiler to store 'counter' in a CPU register.
// This is often used for frequently accessed variables like loop counters.
register int counter;
printf("Demonstrating a register variable in a loop.\n");
for (counter = 1; counter <= 5; counter++) {
printf("Counter value: %d\n", counter);
}
// The following line, if uncommented, will cause a compilation error:
//
// printf("Address of counter: %p", &counter);
//
// Error message would be similar to: "error: address of register variable
‘counter’ requested"
// This proves the variable is treated differently from one in memory.
printf("\nNote: We cannot get the memory address of a register
variable.\n");
return 0;
}
Expected Output:
Demonstrating a register variable in a loop.
Counter value: 1
Counter value: 2
Counter value: 3
Counter value: 4
Counter value: 5
Note: We cannot get the memory address of a register variable.
Storage Class भनेको के हो?
// Do not write the following in your NOTE copy//
Storage Class भन्नाले variable हरू कहाँबाट देखिन्छ (scope), कति समयसम्म
बाँच्छ (lifetime), र कहाँ स्टोर हुन्छ (memory location) भन्ने कुरा बताउँछ।
यसले variable को काम गर्ने क्षेत्र (area of work) र समय (time) निर्धारण
गर्छ।
1. auto
✔ सामान्य variable जसलाई function भित्र बनाइन्छ।
✔ function समाप्त भएपछि मर्छ (variable destroy)।
✔ default मा सबै local variable auto नै हुन्छ।
Example:
#include <stdio.h>
int main()
{
auto int num = 10; // auto variable
printf("Auto variable: %d\n", num);
return 0;
}
Output:
Auto variable: 10
2. register
❖ यो variable लाई CPU register मा राख्न खोजिन्छ (छिटो काम होस्
भनेर)।
❖ धेरै memory मा नपढेर सिधै processor बाट काम गर्छ।
❖ Address लिन सकिँदैन (& प्रयोग गर्न मिल्दैन)।
Example:
#include <stdio.h>
int main()
{
register int fast = 5; // register variable
printf("Register variable: %d\n", fast);
return 0;
}
Output:
Register variable: 5
3. static
➢ function भित्र भए पनि variable बारम्बार जोगिइरहन्छ (retains
value)।
➢ पहिलो पटक मात्रै value initialize हुन्छ।
➢ program सकिएपछि मात्र मर्छ।
Example:
#include <stdio.h>
void display()
{
static int count = 0; // static variable
count++;
printf("Static count: %d\n", count);
}
int main()
{
display(); // 1
display(); // 2
display(); // 3
return 0;
}
Output:
Static count: 1
Static count: 2
Static count: 3
4. extern
✔ एउटा variable अरू file बाट ल्याउने भनेर जनाउँछ।
✔ यो globally define गरिएको variable हो।
Example:
#include <stdio.h>
int num = 50; // global variable
int main()
{
extern int num; // already declared above
printf("Extern variable: %d\n", num);
return 0;
}
Output:
Extern variable: 50
Storage Class Scope (कहाँबाट देखिन्छ) Lifetime (कति समय बाँच्छ) Default value
auto Function/block भित्र Function सकिएपछि मर्छ Garbage/Unknown
register Function/block भित्र Function सकिएपछि मर्छ Garbage/Unknown
static Function/block भित्र Program सकिएसम्म 0
extern सबै ठाउँ Program सकिएसम्म 0
• auto = साधारण variable (function सकिएपछि मर्छ(destroy))।
• register = छिटो चल्ने variable।
• static = पटक पटक चल्दा पुरानो value बचाएर राख्ने।
• extern = अरू ठाउँबाट ल्याइएको variable।