โ‰ก Menu

C Static Variables and Static Functions Explained with Examples

In C language, the life time and scope of a variable is defined by its storage class.

The following are four types of storage class available in C language.

  1. auto
  2. register
  3. extern
  4. static

In this article, we will discuss the ‘static’ storage class and explain how to use static variables and static functions in C with some sample code snippets.

Before moving ahead, lets quickly understand the difference between life time and scope of a variable. A region in code where a variable can be accessed is known as its scope and the duration during which a variable remains active is known as its life time.

I. Static Variables

1. Impact on Life Time

static variables are those variables whose life time remains equal to the life time of the program. Any local or global variable can be made static depending upon what the logic expects out of that variable. Lets consider the following example :

#include<stdio.h>

char** func_Str();

int main(void)
{
    char **ptr = NULL;

    ptr = func_Str();
    printf("\n [%s] \n",*ptr);

    return 0;
}

char** func_Str()
{
    char *p = "Linux";
    return &p;
}

In the code above, the function ‘func_str()’ returns the address of the pointer ‘p’ to the calling function which uses it further to print the string ‘Linux’ to the user through ‘printf()’. Lets look at the output :

$ ./static 

 [Linux]
$

The output above is as expected. So, is everything fine here? Well, there is a hidden problem in the code. More specifically, its the return value of the function ‘func_Str()’. The value being returned is the address of the local pointer variable ‘p’. Since ‘p’ is local to the function so as soon as the function returns, the lifetime of this variable is over and hence its memory location becomes free for any further modifications.

Lets prove this observation. Look at the code below :

#include<stdio.h>

char** func1_Str();
char** func2_Str();

int main(void)
{
    char **ptr1 = NULL;
    char **ptr2 = NULL;

    ptr1 = func1_Str();
    printf("\n [%s] \n",*ptr1);

    ptr2 = func2_Str();
    printf("\n [%s] \n",*ptr2);

    printf("\n [%s] \n",*ptr1);

    return 0;
}

char** func1_Str()
{
    char *p = "Linux";
    return &p;
}

char** func2_Str()
{
    char *p = "Windows";
    return &p;
}

In the code above, now there are two functions ‘func1_Str()’ and ‘func2_Str()’. The logical problem remains the same here too. Each of these function returns the address of its local variable. In the main() function, the address returned by the func1_Str() is used to print the string ‘Linux’ (as pointed by its local pointer variable) and the address returned by the function func2_Str() is used to print the string ‘Windows’ (as pointed by its local pointer variable). An extra step towards the end of the main() function is done by again using the address returned by func1_Str() to print the string ‘Linux’.

Now, lets see the output :

$ ./static 

 [Linux] 

 [Windows] 

 [Windows]
$

The output above is not as per expectations. The third print should have been ‘Linux’ instead of ‘Windows’. Well, I’d rather say that the above output was expected. Its just the correct scenario that exposed the loophole in the code.

Lets go a bit more deep to see what happened after address of local variable was returned. See the code below :

#include<stdio.h>

char** func1_Str();
char** func2_Str();

int main(void)
{
    char **ptr1 = NULL;
    char **ptr2 = NULL;

    ptr1 = func1_Str();
    printf("\n [%s] :: func1_Str() address = [%p], its returned address is [%p]\n",*ptr1,(void*)func1_Str,(void*)ptr1);

    ptr2 = func2_Str();
    printf("\n [%s] :: func2_Str()address = [%p], its returned address is [%p]\n",*ptr2,(void*)func2_Str,(void*)ptr2);

    printf("\n [%s] [%p]\n",*ptr1,(void*)ptr1);

    return 0;
}

char** func1_Str()
{
    char *p = "Linux";
    return &p;
}

char** func2_Str()
{
    char *p = "Windows";
    return &p;
}

The code is above is modified to print the address of the functions and the address of their respective local pointer variables. Here is the output :

$ ./static 

 [Linux] :: func1_Str() address = [0x4005d5], its returned address is [0x7fff705e9378]

 [Windows] :: func2_Str()address = [0x4005e7], its returned address is [0x7fff705e9378]

 [Windows] [0x7fff705e9378]
$

The above output makes it clear that once the lifetime of the local variable of the function ‘func1_Str()’ gets over then same memory address is being used for the local pointer variable of the function ‘func2_Str()’ and hence the third print is ‘Windows’ and not ‘Linux’.

So, now we see what that the root of the problem is the life time of the pointer variables. This is where the ‘static’ storage class comes to rescue. As already discussed the static storage class makes the lifetime of a variable equal to that of the program. So, lets make the local pointer variables as static and then see the output :

#include<stdio.h>

char** func1_Str();
char** func2_Str();

int main(void)
{
    char **ptr1 = NULL;
    char **ptr2 = NULL;

    ptr1 = func1_Str();
    printf("\n [%s] :: func1_Str() address = [%p], its returned address is [%p]\n",*ptr1,(void*)func1_Str,(void*)ptr1);

    ptr2 = func2_Str();
    printf("\n [%s] :: func2_Str()address = [%p], its returned address is [%p]\n",*ptr2,(void*)func2_Str,(void*)ptr2);

    printf("\n [%s] [%p]\n",*ptr1,(void*)ptr1);

    return 0;
}

char** func1_Str()
{
    static char *p = "Linux";
    return &p;
}

char** func2_Str()
{
    static char *p = "Windows";
    return &p;
}

Note that in code above, the pointers were made static. Here is the output :

$ ./static 

 [Linux] :: func1_Str() address = [0x4005d5], its returned address is [0x601028]

 [Windows] :: func2_Str()address = [0x4005e0], its returned address is [0x601020]

 [Linux] [0x601028]

So we see that after making the variables as static, the lifetime of the variables becomes equal to that of the program.

On a related note, if you are not familiar with C pointers, this C pointer series of articles should give you aย jump start.

2. Impact on Scope

In case where code is spread over multiple files, the static storage type can be used to limit the scope of a variable to a particular file. For example, if we have a variable ‘count’ in one file and we want to have another variable with same name in some other file, then in that case one of the variable has to be made static. The following example illustrates it :

Here we use two files (static.c and static_1.c)

//static.c

#include<stdio.h>

int count = 1;

int main(void)
{
    printf("\n count = [%d]\n",count);

    return 0;
}
// static_1.c

#include<stdio.h>

int count = 4;

int func(void)
{
    printf("\n count = [%d]\n",count);
    return 0;
}

Now, when both the files are compiled and linked together to form a single executable, here is the error that is thrown by gcc :

$ gcc -Wall static.c static_1.c -o static
/tmp/ccwO66em.o:(.data+0x0): multiple definition of `count'
/tmp/ccGwx5t4.o:(.data+0x0): first defined here
collect2: ld returned 1 exit status
$

So we see that gcc complains of multiple declarations of the variable ‘count’.

As a corrective measure, this time one of the ‘count’ variable is made static :

//static.c

#include<stdio.h>

static int count = 1;

int main(void)
{
    printf("\n count = [%d]\n",count);

    return 0;
}
// static_1.c

#include<stdio.h>

int count = 4;

int func(void)
{
    printf("\n count = [%d]\n",count);
    return 0;
}

Now, if both the files are compiled and linked together :

$ gcc -Wall static.c static_1.c -o static
$

So we see that no error is thrown this time because static limited the scope of the variable ‘count’ in file static.c to the file itself.

II. Static Functions

By default any function that is defined in a C file is extern. This means that the function can be used in any other source file of the same code/project (which gets compiled as separate translational unit). Now, if there is a situation where the access to a function is to be limited to the file in which it is defined or if a function with same name is desired in some other file of the same code/project then the functions in C can be made static.

Extending the same example that was used in previous section, suppose we have two files :

//static.c

#include<stdio.h>

void func();

int main(void)
{
    func();
    return 0;
}

void funcNew()
{
    printf("\n Hi, I am a normal function\n");
}
// static_1.c

#include<stdio.h>

void funcNew();

int func(void)
{
    funcNew();
    return 0;
}

If we compile, link and run the code above :

$ gcc -Wall static.c static_1.c -o static
$ ./static 

 Hi, I am a normal function
$

So we see that the function funcNew() was defined in one file and successfully got called from the other. Now, if the file static_1.c wants to have its own funcNew(), ie :

// static_1.c

#include<stdio.h>

void funcNew();

int func(void)
{
    funcNew();
    return 0;
}

void funcNew()
{
    printf("\n Hi, I am a normal function\n");
}

Now, if both the files are compiled and linked together :

$gcc -Wall static.c static_1.c -o static
/tmp/ccqI0jsP.o: In function `funcNew':
static_1.c:(.text+0x15): multiple definition of `funcNew'
/tmp/ccUO2XFS.o:static.c:(.text+0x15): first defined here
collect2: ld returned 1 exit status
$

So we see that the compiler complains of multiple definitions of the function funcNew(). So, we make the funcNew() in static_1.c as static :

// static_1.c

#include<stdio.h>

static void funcNew();

int func(void)
{
    funcNew();
    return 0;
}

static void funcNew()
{
    printf("\n Hi, I am also a normal function\n");
}

Now, if we compile, then we see that the compiler never complains :

$ gcc -Wall static.c static_1.c -o static
$ ./static 

 Hi, I am also a normal function
$

Similarly, if static.c wants that its funcNew() should be accessible from within static.c only then in that case funcNew() in static.c can be made static.

Add your comment

If you enjoyed this article, you might also like..

  1. 50 Linux Sysadmin Tutorials
  2. 50 Most Frequently Used Linux Commands (With Examples)
  3. Top 25 Best Linux Performance Monitoring and Debugging Tools
  4. Mommy, I found it! โ€“ 15 Practical Linux Find Command Examples
  5. Linux 101 Hacks 2nd Edition eBook Linux 101 Hacks Book

Bash 101 Hacks Book Sed and Awk 101 Hacks Book Nagios Core 3 Book Vim 101 Hacks Book

Comments on this entry are closed.

  • Jalal Hajigholamali August 3, 2012, 9:30 am

    Hi,

    Thanks a lot,
    I sent this article to my students in university

  • Himanshu Arora August 3, 2012, 11:37 am

    @Jalal
    Thanks for the appreciation.

  • Bobbum_Man August 3, 2012, 12:15 pm

    Nice article. Could you also explain what Register storage class means?

  • Thiago Jobson August 5, 2012, 9:58 am

    Great article.
    There was another thing I did not know :
    “By default any function that is defined in a C file is extern. ”

    Thanks alot;

  • Jay August 8, 2012, 1:26 am

    Awesome article. Really cleared up quite a few doubts. Keep up the good work ๐Ÿ™‚

  • Adorn August 8, 2012, 8:18 am

    Basic thing Explained very neatly!

  • Tariq November 8, 2012, 2:58 pm

    I am wondering why Himanshu is using double pointer to point to the character. Secondly, if the local memory is gone after the function returns, why is Linux getting printed in the first example?

  • nikoo28 January 29, 2013, 9:45 am

    Thanks a lot for this article…really really helpful….

  • Anjaneya Alluri January 30, 2013, 10:14 pm

    while explaining Impact of static on Lifetime , the second printf statement of (*ptr1) is returning null.( not windows ).
    My main doubt is , why did it even print the value of Linux the first time ?
    Also , if i try to add a second printf immediately after my first printf of (*ptr1) , even then it is printing null.

    So its printing only once . why ?

  • Neo February 14, 2013, 10:09 pm

    Its really helpful!!! Thanks for posting! ๐Ÿ™‚

  • Gufran February 27, 2013, 1:28 am

    Many many thanks buddy for posting such a great article ๐Ÿ™‚

  • Balaganesh March 8, 2013, 7:07 am

    This case is before using static keyword:
    How the local variable contents are printed in main (). Actually the stack created for each function will get destroyed once we return from it.But how it gets printed ???
    And whether the 2 functions are using the same stacks ??? because the address are same

  • Chanchal March 30, 2013, 12:20 am

    A great tutorial, really liked it..

  • mohd salman May 22, 2013, 11:47 pm

    hi, i m salman BCA 2nd sem. this website is very usefull for my and your study. I realy thanks for it.

  • vineet kumar June 12, 2013, 8:18 am

    Thanks for explaining so clearly about the static variable and funtions.
    Thanks alot

  • anuj August 9, 2013, 2:48 pm

    nice work

  • Tejas Patel August 28, 2013, 12:12 am

    Excellent job.

  • jameel Ahmed September 18, 2013, 11:48 am

    Hi
    could u please explain the use of double pointer in the programs u have used

  • akg September 24, 2013, 4:22 am

    good job…

  • Nahla October 1, 2013, 8:06 pm

    Thanks so much it very useful

  • dbhat October 9, 2013, 2:57 am

    Thanks a lot …. Nice work ๐Ÿ™‚

  • Daniel Mendonรงa October 9, 2013, 7:31 pm

    Wow, thanks a lot, really easy to understand your examples, and the use of it.
    Thanks

  • Anil October 22, 2013, 6:22 am

    than k u so much …for posting…nice articel,i have read so many websites about the static functions no one explained clearly…really….than k u so much….

  • Krishna Narendrula October 29, 2013, 12:15 am

    Hi,

    Thanks a lot for this….I am expecting some more

  • vijay November 12, 2013, 10:06 am

    excellent..

  • WicTy December 19, 2013, 6:33 am

    This is super awesome. Thank you!

  • anurag March 20, 2014, 5:01 am

    how does the value of the local variable get printed despite it being destroyed from the stack once the function returns.

  • Gene April 17, 2014, 2:57 pm

    Very good explanation. I just needed a confirmation of what I already guessed is true about local variables and lifetimes. Thank you.

  • Swaroop May 13, 2014, 11:23 pm

    Thank for great explanation..

  • Vinay Gayki May 21, 2014, 12:56 am

    well explained ,good job ..thanks ๐Ÿ™‚

  • Karthik May 25, 2014, 10:18 pm

    Thank you vary much Sir,
    but I have one small doubt. As follows
    #include

    char** func1_Str();
    char** func2_Str();

    int main(void)
    {
    char **ptr1 = NULL;
    char **ptr2 = NULL;

    ptr1 = func1_Str();
    printf(“\n [%s] :: func1_Str() address = [%p], its returned address is [%p]\n”,*ptr1,(void*)func1_Str,(void*)ptr1);

    ptr2 = func2_Str();
    printf(“\n [%s] :: func2_Str()address = [%p], its returned address is [%p]\n”,*ptr2,(void*)func2_Str,(void*)ptr2);

    printf(“\n [%s] [%p]\n”,*ptr1,(void*)ptr1);

    return 0;
    }

    char** func1_Str()
    {
    static char *p = “Linux”;
    return &p;
    }

    char** func2_Str()
    {
    static char *p = “Windows”;
    return &p;
    }
    In this example can we use global variables instead of static? If it is then what is the specific usage of static variable here?

  • Anonymous July 22, 2014, 5:13 am

    nicely done! thanks a lot!

  • radhika August 9, 2014, 11:06 am

    thanx for the artical

  • Prankur Chauhan August 26, 2014, 7:11 am

    Good Article

  • Abhinav Jha November 6, 2014, 1:04 am

    Thank you very much sir….you shortens all confusions about the static variables..

  • kavya December 17, 2014, 9:41 am

    Its cool …sir bt
    where did we mostly use dese static programs in our day to day life

  • kavya December 17, 2014, 9:46 am

    dats cool…….sir.bt
    we did use dese c-static programming in our day to day life

  • Sravan January 17, 2015, 3:03 am

    Thanks so much for the article.

  • Bittu abi May 15, 2015, 11:00 am

    thanxx sir

  • Anil antony May 16, 2015, 4:29 am

    Hai kavya, we use static variables and static functions in embedded system design. Eg. Device driver programming.

  • sivananda May 20, 2015, 8:32 am

    Thanks for the article. great article.

  • shiva July 4, 2015, 12:52 am

    good artical

  • prasad July 15, 2015, 10:06 am

    good explanation

  • yamuna September 13, 2015, 7:53 am

    If static storage in c will not work then what problem will you face?

  • Ajay November 5, 2015, 3:07 am

    Very useful thanks for very neat explanation

  • Manimaran J December 25, 2015, 2:27 am

    I can understand clearly about what is static?. Keep similar resource consistently. Thank you.

  • Aditi February 8, 2016, 11:05 pm

    Great explanation!