The compilation process is complicated but interesting in c language. If a program has multiple files then each file compiles individually and creates the object of each source file.

The important role of linkers comes after the creation of object files. It performs two important task symbol resolution and relocation. The linker takes each object file and creates one absolute object file.

When the linking process starts, linkage property comes into the play. In this article, I will not discuss the linker, I will only discuss the linkage.

According to C standards, “An identifier declared in different scopes or in the same scope more than once can be made to refer to the same object or function by a process called linkage”.

In this article, I have used a term translation unit many times, so first, we have to understand, what is the translation unit?

A source file together with all the headers and source files included via the preprocessing directive #include is known as a preprocessing translation unit. After preprocessing, a preprocessing translation unit is called a translation unit.

Note: If you want to learn C Programming, I recommended you to see this video Course.

There are three kinds of linkage: external, internal, and none

External Linkage in C:

If an identifier has file scope and does not use the static storage class specifier at the time of the first declaration, the identifier has the external linkage.

The externally linked identifier or function visible to all translation unit of the program that means we can access it any translation unit of the program.

By default, all global identifier has the external linkage and each declaration of a particular identifier with external linkage denotes the same object or function.

In C language, extern keyword establishes external linkage. When we use the extern keyword, we say to the linker that the definition of the identifier can be in another file. The externally linked identifier is accessed by any translation unit that’s why it generally stored in an initialized/uninitialized or text segment of RAM.



Let see an example to understand the external linkage.

Suppose in a program there are two files Driver.c and Calculation.c. Now the requirement is to share an identifier between these two files to get the result. I have written down a sample code to describe the external linkage.

Driver.C

#include <stdio.h> int Amount = 0; //External Linkage int main() { Addition(); //function define in other file. printf("%d

", Amount); //Display amount return 0; }

Calculation.C

void Addition() { int a = 0, b = 0; printf("Enter the value

"); scanf("%d%d",&a,&b); Amount = a + b; }

In the above program, Amount has external linkage, its definition is available for all translation units. But when we will compile the above program, we will get the compiler error. This compiler error is coming because when cursor comes to the Amount in Calculation.c then it found it as an undeclared identifier.

In the above scenario, the linker is not able to resolve the symbol resolution at the time of linking for the identifier (Amount). So we have to declare “Amount” in Calculation.c, here extern play an important role.

Driver.C

#include <stdio.h> int Amount = 0; int main() { Addition(); printf("%d

", Amount); return 0; }

Calculation.C

extern int Amount; void Addition() { int a = 0, b = 0; printf("Enter the value

"); scanf("%d%d",&a,&b); Amount = a + b; }

After the modification, if we compile the code, it is compiled perfectly. The “Amount” is marked as an “unresolved” references in “Calculation.o”.

When both object files are passed to the linker, the linker determines the values of the “unresolved” references from the other object files and patches the code with the correct values.

Internal Linkage in C:

If a global identifier declares with static storage class, its linkage will be internal. An identifier implementing internal linkage is not accessible outside the translation unit in which it is declared.

An identifier with internal linkage denotes the same object or function within one translation unit if it is accessed by any function.

Let see an example to understand the internal linkage.

Suppose in a program there are two files Message.c and Driver.c. Here Driver.c contains an identifier “Amount” and I want to make this identifier private to Driver.c.

So we have to declare the identifier with a static storage class. The linkage of the identifier is internal and it will only visible to Driver.c

Message.C

#include <stdio.h> int Display(void) { printf("%d ",Amount); }

Driver.C

#include <stdio.h> static int Amount = 10; int main() { Display(); return 0; }

The above code implements static linkage on “Amount”. So when we will compile the above code get the compiler error because “Amount” is accessed in the Message .c.

But when we will access the “Amount” within the translation unit, we will not get any compiler error.

#include <stdio.h> static int Amount = 10; int Display(void) { printf("%d ",Amount); return 0; } int main() { Display(); return 0; }









None linkage in C:

A local variable has no linkage and refers to unique entities. If an identifier has the same name in another scope, they do not refer to the same object.

See the below code,

#include <stdio.h> int Display1(void) { int Amount = 20; printf("%d ",Amount); } int Display2(void) { int Amount = 30; printf("%d ",Amount); } int main() { int Amount = 10; Display1(); Display2(); return 0; }

If we compile the above code, we will get 20 and 30 as output. You can see “Amount” is unique for the Display1, Display2, and main function.

If you want to access the automatic variable in other functions, you need to pass it as a parameter.

Recommended Posts for you