10.5 – Storage classes – auto, extern

by subbu on November 28, 2013

How can we declare a variable in C?

A variable is a name for a piece of memory in the RAM, which can be used to store the data. The declaration statement tells the compiler that what type of value that it has to store (type), how far it can be accessed (scope), how long it must be existed in the memory (life) and where should it be stored?

While declaring a variable, we need to use both the storage class specifier and the data type. Where  data type specifies the property of a variable that is what type of value need to be stored and the storage class specifier specifies the scope, life and storage location of a variable.

How to declare a variable in C

auto storage class in C language:

So far we have been declaring one or more variables in every program but, has been using only data type. We have not used any storage class specifier with the variable declaration statements so far.

C compiler takes auto storage class specifier, if we don’t write any storage specifier while declaring a local variable in a function. So the default storage class specifier of a local (automatic) variable is auto. Say for example the meaning of

int x;

in a function is

auto int x;

So, auto is the storage class specifier used to declare local variables but, it is optional to write auto while declaring local variables.

Scope, life and storage of auto storage class in C:

auto variables are nothing but, local or automatic variables of any function. Scope, life and storage of auto variables is same as scope, life and storage of local or internal variables.
Scope: limited to the home function
Life: appears as control enters into the function and disappears on completion of function execution
Storage: In stack memory which is private to the function.
Default value: Garbage value

Note: Refer 10.2 – Internal or local variables in C session for detailed explanation and example programs on local variables. In all the example programs, you can use auto storage class specifier with every variable declaration statement.

extern storage class in C language:

Variables defined out side the functions are called external or global variables. These variables can be accessed from the functions which are down to their definition but, can’t be accessed from the functions which are above to their definition. Let us recall an example from the previous session 10.3 – External or global variables scope.

Example:

/* scope of external variables */
#include<stdio.h>
void display();
int main()
{
 printf("x=%d",x);
 display();
 printf("\nx=%d",x);
 return 0;
}
int x=10;         /* defining external variable  */
void display()
{
 printf("\nx=%d",x);
 x=x+50;
}

Output:
Error: undefined symbol “x” in function main().

Here in this example, x is an external variable because declared outside both the function main() and display().
Because it is defined below to the main() and above to the display(), It is global to display() but, not to the main(). Hence x can’t be accessed from the main(), which results error.

It can be rectified by declaring the external variable x in the main() using the storage class specifier extern. It informs the compiler that, x is an external variable defined some where else in the code and capable to get into the main().

Example:

/* scope of external variables */
#include<stdio.h>
void display();
int main()
{
 extern int x;          /* declaration of extern variable */
 printf("x=%d",x);
 display();
 printf("\nx=%d",x);
 return 0;
}
int x=10;               /* defining external variable  */
void display()
{
 printf("\nx=%d",x);
 x=x+50;
}

Output:
x=10
x=10
x=60

Example explained:

extending scope of external variables

Generally scope of “x” is limited to the function display(). As “x” is declared with storage class specifier extern, its visibility is extended to main() also.

Example:

#include<stdio.h>
void first();
void second();
int main()
{
 extern int x;                   /* declaration in main() */
 first();
 second();
 printf("\nx=%d",x);
 return 0;
}
void first()
{
 extern int x;      /* declaration in first()  */
 printf("x=%d",x);
 x=x+10;
}
int x=10;          /* definition of external variable */
void second()
{
 printf("\nx=%d",x);
 x=x+10;
}

Output:
x=10
x=20
x=30

Example explained:
In the above example, “x” can be accessed only from the second() but not from any other functions as it is defined above to the function second() and below to the functions main() and first()
If we declare “extern int x;” before the main() then x can be accessed from all the functions above from the definition.
If we want to access “x” from any particular function then extern declaration is done only in that particular function.

Declaration vs. Definition:

I have never used a phrase defining a variable in any of the previous sessions except in the context of external variables. In case of external variables, definition is different from declaration.

int x=10;     /* definition */

Here it is the definition of a variable x, which actually selects a piece of memory in the data segment

extern int x;  /*declaration */

Here it is the declaration of an external variable, it just informs the compiler regarding to the external variable x and improves its scope.

Note: External variables can be defined only once in an application but, can be declared any number of times.

external variables can be initialized while defining but, can’t be initialized while declaring

extern int x=10;     /* It is invalid */
int x=10;            /* It is valid    */

extern with arrays:

extern storage class specifier can be applied even with the array but, the size must be specified with the definition, optional with the extern declaration.

Example:


#include<stdio.h>
void input();
int main()
{
 extern int x[]; /* size is optional */
 int i;
 input();
 printf("Given elements are:\n");
 for(i=0;i<5;i++)
 printf("%5d",x[i]);
 return 0;
}
int x[5]; /* size is compulsory */
void input()
{
 int i;
 printf("Enter 5 elements:\n");
 for(i=0;i<5;i++)
 scanf("%d",&x[i]);
}

Execution:
Enter 5 elements:
34 23 44 66 78
Given elements are:
34 23 44 66 78

If an external array is being initialized while its declaration then specifying the size with the definition is not mandatory

Example:

#include<stdio.h>
void process();
int main()
{
 extern int x[];                      /* size is optional      */
 int i;
 process();
 for(i=0;i<5;i++)
   printf("%5d",x[i]);
 return 0;
}
int x[]={12,45,67,87,23};            /* size is optional */
void process()
{
 int i;
 for(i=0;i<5;i++)
   x[i]=x[i]+10;
}

Output:
22      55      77      97      33

Extending the scope of external variables in multiple files:

For the development convenience, the source code of an application may be parted into number of source files and connected properly so that all the pieces will be properly connected when the application is loaded (will be covered under pre-processor directives).

In situation like this, external variables defined in one source file may not be accessed into other source file but, can be accessed by declaring the external variable using extern in the required function or file.

Handling multiple files in C language

Here x is an external variable defined in file2, can’t be accessed into file1 because it’s scope is along the file2 only. It can be accessed into file1 by declaring x in file1 using extern storage class specifier.

In the above case x is declared in the function first(). Hence can only be accessed within the function first().

Extending the scope of variables to other files

x can be access along the file1, if declared above all the functions using extern declaration.

Conclusion:

  • extern storage class specifier is only used to declare external variables to extend their scope to other portions of the program or files
  • external variable can be initialized only when defining but, not at the time of declaration using extern
  • external variable can be defined only once but, can be declared any number of times.
  • Size must be given while defining external array but, not needed while declaring

Previous post:

Next post: