C Scope and Lifetime

The scope of a variable is the part of the program within which the variable can be used. So, the scope describes the visibility of an identifier within the program.

The lifetime of a variable or function is the time duration for which memory is allocated to store it, and when that memory is released. It also refered as extent of a variable.

The scope and lifetime of a variable are central design issues which defines the interaction between data and functions.

Local Scope

A variable declared within a function has a local scope by default. This means that it is visible only to the block in which it is defined. A block of a code is a segment enclosed in braces {…}.

Function arguments also have local scope. For example, in the following function,

/* This function takes two int arguments, and returns an int. */
int add_integers(int int1, int int2)
{
    int sum = int1 + int2;

    {   //begining of block scope
        int local_variable = 300;
        printf("Inside block: local_variable = %d \n",local_variable);
    }   //end of block scope; local_variable goes out of scope 
    
    //printf("outside block: local_variable = %d",local_variable); //this causes an error as local_variable
                                                                   // is already dead

    printf("Inside function, outside block: sum = %d \n",sum);
    return sum;
} //end of function; int1, int2, sum goes out of scope

So, if you invoke add_integers(int,int) as

int result = add_integers(4,5);

The output will be:

Inside block: local_variable = 300 
Inside function, outside block: sum = 9

Here, int1, int2 and sum are local variable to function add_integers(int,int) and local_variable is local to block inside this function. If you try to access local_variable outside that block, you'll get a compiler error.

External Scope (aka Global scope)

A variable defined outside of any function is an external variable, by default. Scope for these variable is called external scope or program scope.

External variables and functions are visible over the entire program which may contain multiple files. In other words, a function can be called from any function with in the program.

Similarly, an external variable can be accessed or changed by any function with a program. However, it is necessary to first declare a variable or function in each file before it is used.

The extern keyword is used to declare the existence of an external variable in one file when it is defined in another. Function prototypes may also be preceded by extern, but this is not essential as they are external by default.

Let us look at the simplest program to define and print global variable.

#include <stdio.h>

/* global variable declaration */
int global_num = 20;

int main ()
{
    printf("global_num = %d \n",global_num);

    global_num = 50;
    printf("New global_num = %d \n",global_num);

    return 0;
}

The output of the program is:

global_num = 20
New global_num = 50

After printing the value of global variable, it is changed to new value which is verified by printing it.

The following example has two files and external variable and function shared between them.

File first.c:
   int global_var; /* external variable definition */
   extern double my_variable; /* external variable declaration (defined elsewhere) */
   void my_function(int idx); /* external function prototype (declaration) */

File second.c:
   double my_variable = 3.2; /* external variable definition */
   void my_function(int idx)
   /* Function definition */
   {
     extern int global_var; /* external variable declaration */
     ...
   }

These two files should be saved under same folder ( or directory or package) in order for them to share the data and function.

Scope resoultion and name hiding

It is possible for a program to have two variables of the same name with overlapping scope such that they are potentially visible from the same place. In such situations, one variable will hide the other. This is called name hiding.

C specifies that the variable with more restricted scope will be visible, and the other hidden. In other words, the variable that is “more local” has dominant visibility.

The following program helps to understand more about name hiding and scope resoultion.

/* program to illustrate name hiding and scope resolution */
#include<stdio.h>

/* global variables */
int int1 = 10;
/* This function takes two int arguments, and returns an int. */
int add_integers(int int1, int int2)
{
    int sum = int1 + int2;

    {
        //begining of block scope
        int sum = 300;
        printf("Inside block: sum = %d \n",sum);
    }   //end of block scope; sum goes out of scope

    printf("Inside function, outside block: sum = %d \n",sum);
    return sum;
} //end of function; int1, int2, sum goes out of scope

/* A function that calls add_integers() */
void caller_function(void)
{
    int num1=1, num2=2,result;  //num1 supresses global num1
    result = add_integers(num1,num2); /* result = 3 */
    printf("Sum : %d",result);
}

int main()
{
    printf("Global int1= %d \n",int1);  //prints global value of int1 i.e. 10
    caller_function();
    return 0;
}

The output of the program is:

Global int1 = 10 
Inside block : sum = 300 
Inside function, outside block : sum = 3 
Sum : 3

Here, inside main(), global int1 gets printed. When add_integers(int,int) gets called, the parameters, which are local to that function, gets added. Inside scope, which is inside function add_integers(int,int), the value of sum suppresses value outside that scope.

C Storage Classes
C Recursion