Static and Extern in C

Introduction

The keyword static and extern have been commonly to limit the storage duration and linkage of variables and functions in C.

In this blog post, I would like to quickly discuss static and extern in C and show a self-explanatory example.

Static and Extern

The keyword static and extern affects the storage duration a variable and the linkage of a variable or a function.

  • static - static duration and internal linkage
  • extern - static duration and external linkage

The static storage duration is the entire execution of the program, and the value stored in the object is initialized only once, prior to main function.

With internal linkage, the identifier can be referred to from all scopes in the current translation unit. All static file-scope identifiers (both functions and variables) have this linkage.

With external linkage, the identifier can be referred to from any other translation units in the entire program. All non-static functions, all extern variables (unless earlier declared static), and all file-scope non-static variables have this linkage.

Example

Here is a self-explanatory example on demonstrating the use cases of static and extern.

lib.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <stdio.h>

/* Static variable is local to this file. */
/* other files can also have a variable of the same name. */
static int i = 0;

/* External variable j from other files. */
extern int j;

/* Static function local to this file. */
static void hello_heaven()
{
printf("-----------------------------------------------\n");
printf("hello_heaven called from lib\n");
}

/* extern void hello_world(); */
/* extern is not needed since declaration always refers extern for
* implementation. */
void hello_world();

/* Static function shortcut */
void hello_heaven_shortcut() { hello_heaven(); }

int a = 5;

void hello_underworld()
{
static int k = 0;
i++;
j++;
k++;
printf("-----------------------------------------------\n");
printf("hello_underworld called from lib\n");
printf("static variable i from lib: %d\n", i);
printf("extern variable j from lib: %d\n", j);
printf("static variable k from lib hello_underworld: %d\n", k);
hello_world();
}
lib.h
1
2
3
void hello_heaven();
void hello_heaven_shortcut();
void hello_underworld();
main.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include "lib.h"
#include <stdio.h>

static int i = 0;

int j = 0;

/* multiple definition of `a' during linking since it's defined elsewhere */
/* int a = 10; */

void hello_world()
{
i++;
j++;
printf("-----------------------------------------------\n");
printf("hello_world called from main\n");
printf("static variable i from main: %d\n", i);
printf("extern variable j from main: %d\n", j);
}

int main()
{
/* undefined reference to `hello_heaven' during linking since it's static in
* lib.c */
/* hello_heaven(); */
hello_heaven_shortcut();
hello_world();
hello_world();
hello_world();
hello_underworld();
hello_underworld();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
$ gcc -c lib.c -o lib.o
$ gcc -c main.c -o main.o
$ gcc -o main main.o lib.o
$ ./main
-----------------------------------------------
hello_heaven called from lib
-----------------------------------------------
hello_world called from main
static variable i from main: 1
extern variable j from main: 1
-----------------------------------------------
hello_world called from main
static variable i from main: 2
extern variable j from main: 2
-----------------------------------------------
hello_world called from main
static variable i from main: 3
extern variable j from main: 3
-----------------------------------------------
hello_underworld called from lib
static variable i from lib: 1
extern variable j from lib: 4
static variable k from lib hello_underworld: 1
-----------------------------------------------
hello_world called from main
static variable i from main: 4
extern variable j from main: 5
-----------------------------------------------
hello_underworld called from lib
static variable i from lib: 2
extern variable j from lib: 6
static variable k from lib hello_underworld: 2
-----------------------------------------------
hello_world called from main
static variable i from main: 5
extern variable j from main: 7

References

Author

Lei Mao

Posted on

11-16-2022

Updated on

11-16-2022

Licensed under


Comments