Open In App

Internal Linkage and External Linkage in C

Last Updated : 02 Apr, 2025
Comments
Improve
Suggest changes
Like Article
Like
Report

In C, linkage is a concept that describes how names/identifiers can or cannot refer to the same entity throughout the whole program or a single translation unit. The above sounds similar to scope, but it is not so. To understand what the above means, let us dig deeper into the compilation process.

Before moving to learn about linkage in C, we first need to understand what a translation unit is.

A translation unit is a file containing source code, header files and other dependencies. All of these sources are grouped together to form a single translation unit which can then be used by the compiler to produce one single executable object.

What is a Linkage?

Assume a C program that consists of multiple source code files. Each source file is compiled one at a time. In the compilation process, the last stage is linking where s multiple machine code files are used to produce an executable object code. It is handled by the program called linker.

Linkage is a property that describes how variables should be linked by the linker.

Should a variable be available for another file to use? Should a variable be used only in the file declared? Both are decided by linkage. Linkage thus allows you to couple names together on a per file basis.

Types of Linkage in C

There are 2 types of linkage in C:

Internal Linkage

An identifier implementing internal linkage is not accessible outside the translation unit it is declared in. Any identifier within the unit can access an identifier having internal linkage. It is implemented by the keyword static. An internally linked identifier is stored in initialized or uninitialized segment of RAM. For example,

Consider a source file: animals.c

C
#include <stdio.h>

// Variable with internal linkage
static int animals = 8;

The above code implements static linkage on identifier animals.

Consider another source file: feed.c is located in the same translation unit using #include

C
#include <stdio.h>
#include "animals.c"

int main() {
  
  	// Accessing variable.
    printf("%d", animals);
    return 0;
}

On compiling and executing feed.c using the following command:

gcc feed.c -o feed
./feed

We get the output,

8

Now, consider that feed.c is located in a different translation unit (means we are not including the animals.c using #include). Trying to compile it using the following command:

gcc feed.c animals.c -o feed
./feed

Compiler will throw an error

feed.c: In function 'main':
feed.c:6:18: error: 'animals' undeclared (first use in this function)
6 | printf("%d", animals);
| ^~~~~~~
feed.c:6:18: note: each undeclared identifier is reported only once for each function it appears in

External Linkage

An identifier implementing external linkage is visible to every translation unit. Externally linked identifiers are shared between translation units and are considered to be located at the outermost level of the program. It is the default linkage for globally scoped variables and functions.

The keyword extern implements external linkage. When we use the keyword extern, we tell the linker to look for the definition elsewhere. Thus, the declaration of an externally linked identifier does not take up any space. Extern identifiers are generally stored in initialized/uninitialized or text segment of RAM.

Take the above example of internal linkage and remove the static keyword.

animals.c

C
#include <stdio.h>

// Variable with external linkage
int animals = 8;

As the variable animals is declared globally, it is accessible to all the translational units.

Now, consider the file feed.c is in the different translational unit

feed.c

C
#include <stdio.h>

// Telling compiler that the variable have
// external linkage
extern int animals;

int main() {
  
  	// Accessing variable.
    printf("%d", animals);
    return 0;
}

Now, compiling and executing both files using the command:

gcc feed.c animals.c -o feed
./feed

We get the output:

8

As we can see, as the variable animals have external linkage, we were able to access it in the other translation unit.

Example of External and Internal Linkage

Let’s take a look at an interesting example of external and internal linkage.

Modify the file animals.c as shown:

C
#include <stdio.h>

// Variable with internal linkage
static int animals = 8;

// Function with external linkage
void printAnimals() {
  	printf("%d\n", animals);
}

Here, animals variable have internal linkage (as it is declared static) while the function printAnimals() have external linkage (as it is declared globally).

Update the feed.c file as well

C
#include <stdio.h>

// Telling compiler that the function have
// external linkage
extern void printAnimals();

int main() {
  
  	printAnimals()
    return 0;
}

Guess what will happen?

If you guessed that the value of animals variable will be printed, then you are correct. It is because we are not accessing the value of animals in other translation unit. We are just accessing the function printAnimals() which is externally linked and in turn belongs to the same translation unit as animals. So it is able to access the value of the variable animals.



Next Article

Similar Reads

  翻译: