External Storage Class and Global Variables


In this tutorial, we will cover the external storage class, also known as the extern storage class, along with the concept of global variables. We will explore the features of the extern storage class and understand why there are situations where we need to define a variable as an external variable. Additionally, we will gain a proper understanding of global variables through examples and learn how they differ from extern variables.


The Syntax

The syntax to declare an external variable is as follows:

extern data_type variable_name;

Examples:

extern int var;

Features of a Static Storage Class

Following are the features of a external storage class:

  1. Storage:  memory.
  2. Default value:  *nothing. 
  3. Scope:  global.
  4. Lifetime:  till the execution of the program comes to an end.

*A variable declared with the keyword “extern” is declared but not defined. As a result, no memory is allocated to it, and it does not have a default value.


Need of External Storage Class

It is sometimes necessary to declare a variable before defining it while writing code. We are already familiar with the distinction between declaration and definition, so let’s review it.

  • Declaration refers to the properties of a variable being declared like its data type and name without memory being allocated to it.
  • Definition refers to the declaration plus memory allocation.

To declare a variable as external, use the keyword extern before the variable name. No memory will be allocated for the variable. The compiler will trust that you have defined the variable elsewhere and will allow you to use it in your code before it is defined. If the variable is not defined anywhere, the compiler will generate an error.

Following program clearly demonstrates how to declare a global external variable, and its use:

#include <stdio.h>

extern int var; // var is declared. Global scope.

int main() {
    printf("%d", var); // var is used before its definition, but no error.
    return 0;
}

int var = 10; //var is defined

Output:

The compiler did not generate an error because the variable was declared as external, even though it was used before its definition.


Global Variable without Extern Keyword

A variable that is declared or defined outside of any function is referred to as a global variable. A global variable can be defined without any storage class by initializing it with a value, just like a regular variable. The following program demonstrates how to define a global variable:

#include <stdio.h>

int var = 20;

int main() {
 printf("%d", var);
 return 0;
}

Output:

The code and the output is self explanatory.

Now, what happens if we won’t initialize a global variable? Will that be a declaration or a definition? This is not as straightforward as it sounds. We need to understand the concept of tentative definitions for this.

Tentative Definitions

A tentative definition is a declaration that may or may not act as a definition. When a global variable doesn’t have a value assigned to it and is not defined and assigned a value elsewhere in the program, the tentative definition is treated as a proper definition.

For instance, in the program below, the variable var has a tentative definition because it is not given an initial value. However, since there is no other place in the program where var is defined and given a value, the tentative definition will act as a valid definition.

#include <stdio.h>

int var; // tentative definition acting as definition

int main() {
   printf("%d", var);
   return 0;
}

Output:

The variable var is assigned a memory and it is initialized to zero because the default value of a global variable is zero. Hence, the output.

If the definition is found before or after the tentative definition, then the tentative definition will act as a declaration. The following program demonstrates the same:

#include <stdio.h>

int var; // tentative definition acting as a declaration

int main() {
    printf("%d", var);
    return 0;
}

int var = 20; // definition of var

Output:

This time, var is acting like an external variable. Isn’t that cool 😎


Resolving Clashes With Global Variables

Consider the following program and try determining the output yourself:

#include <stdio.h>

int var = 10;

int main()
{
    int var = 20;
    printf("%d", var);
    return 0;
}

The output of the above program is

This is because local variables always get preference over global variables.


External Variable Inside a Block

Even though it is recommended to declare external variables outside of any function, it is technically possible to declare them within a block of code. However, using a variable before its definition can lead to a compilation error. The following program illustrates this:

#include <stdio.h>

int main() {
    printf("%d", var); // var is used before its definition. Error!
    return 0;
}

int var = 10; //var is defined

Compiler will generate error “‘var’ undeclared”  in the logs:

The compiler only wants you to declare a variable before its use. One way is to declare a variable outside all the functions like what we did previously. Another way is to declare a variable inside the function where you want to use that variable. The following program demonstrates the same.

#include <stdio.h>

int main() {
    extern int var; // var is declared; not defined.
    printf("%d", var); // No error!
    return 0;
}

int var = 10; //var is defined

Output:

Now, what do you think should be the output of the following program?

#include <stdio.h>

void fun()
{
    printf("%d", var);
}

int main() {
    extern int var;
    printf("%d", var);
    fun();
    return 0;
}

int var = 10;

We will again get the following error:

Notice that we are using var inside the fun() function, but it is not declared before its use. This shows that either a variable should be declared outside all functions or a variable should be declared in all the functions which are using that variable. The correct code is shown below:

#include <stdio.h>

void fun()
{
    extern int var; // var is declared
    printf("%d", var); // No error!
}

int main() {
    extern int var; // var is declared
    printf("%d", var); // No error!
    fun(); // fun function is called
    return 0;
}

int var = 10; // var is defined

Output:


Working with Multiple Source Files

External variables are helpful when we want to use variables defined in other source files. Let’s imagine we have two files, “test1.c” and “test2.c”, located in the same folder. The code in “test2.c” looks like this:

test2.c

int var = 10;

In “test2.c”, the variable var is defined.

Now, let’s say we want to use this variable in “test1.c”. To accomplish this, we can include the “test2.c” file in “test1.c”, similar to how we include header files. The only difference is that “test2.c” should be enclosed in double quotes.

test1.c

#include <stdio.h>
#include "test2.c"    //includes test2.c

int main()
{
    printf("%d", var);
    return 0;
}

Output:

Although the output is correct, it might seem like magic that the value of var appears seemingly out of nowhere. It is generally better to declare the variable that you are going to use from another source file explicitly. Therefore, the following code is considered more valid:

test1.c

#include <stdio.h>
#include "test2.c"    //includes test2.c

extern int var;   // var is declared

int main()
{
    printf("%d", var);
    return 0;
}

Output:

By explicitly declaring var as an external variable using the extern keyword, we make it clear that the variable is defined elsewhere and can be used in the current file.



Leave a comment

Leave a comment

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

Thank you for choosing to leave a comment. Please be aware that all comments are moderated in accordance with our policy. For more information, please review our comments policy. Rest assured that your email address will not be shared with anyone. Kindly refrain from using keywords in your comment. Let’s maintain a respectful atmosphere and engage in meaningful conversations.