C Linkage Complete Tutorial

  • Post author:
  • Post category:C

In this section, we will learn what the linkage is and how it works in C.

What is Linkage in C? (Linkage Definition)

Linkage is the idea of changing the behavior of a variable or even a function in a way that is then accessible or not accessible from other files (transition-unit) of the same program.

In the enterprise C programs (those that are over thousands of lines of code); we can’t just write all the source codes in one file and execute it!

Well, technically speaking, we can do that, but because the file becomes so lengthy, it is really difficult to maintain and manage the source code afterward.

For this reason, it is suggested that we divide the source code into multiple files. That way, managing the source codes becomes a much easier task to do.

Let’s say we have a program like this:

#include <stdio.h>

void printValue(void);
int i = 500;
int main() {

    printValue();
    return  0;
}

void printValue(void){

    printf("%d\n",i);
}

For the sake of demonstration, we’re going to divide this source code into 2 files.

The first file’s name is `main.c` and it contains this portion of the code:

void printValue(void);
int i = 500;
int main() {

    printValue();
    return  0;
}

The second file’s name is `secondFile.c` and it contains this portion of the code:#include <stdio.h>

#include <stdio.h>

void printValue(void){

    printf("%d\n",i);
}

 

Notes:

  • Even though these two source codes are part of the same program, we need to include any necessary header file for any external function in each source code. (Like the use of `printf` function in the `secondFile` necessitates the inclusion of the `stdio.h` header file)
  • The `main.c` file and the `secondFile.c` with its header file, each of them separately is called a transition-unit file. You can learn more about preprocessors in the preprocessors section but for now just remember that compilers move the content of headers to the source code that they are included in and the final source code (with every header file included) becomes an independent file called the Transition Unit. So now we have two transition-units named `main` and `secondFile` for this program.

Now let’s compile and run this program to see if it works correctly!

We put both files in one folder and so in order to compile and run this program, all we need to do is to run the Command Prompt, go to the directory and execute the command below:

`gcc main.c secondFile.c`

command prompt

The moment we tried to compile the program, we got this error:

The variable `i ` is undeclared within the body of `printValue` function.

Basically, it says we’re trying to get the value of a variable in the `secondFile.c` file, but there’s no sign of it!

Yep! Even though both files `main.c` and `secondFile.c` are part of the same program and compiled together, they don’t share variables with each other unless we explicitly tell them to do so!

I think it’s now clear that by default we can’t just access any variable in any file of a program and get or change its value!

In order to make this happen, we need linkage! Let’s what they are now:

Types of Linkage in C

A variable in a program can have one of these three types of linkage:

  • External Linkage
  • Internal Linkage
  • No Linkage

External Linkage

By default, any file-scope variable is POTENTIALLY accessible from other files.

Note: read the scope section if you don’t know what `file-scope` means.

We say potentially because the target file that wants to access the variable needs to re-declare the variable with the specifier `extern`.

The `extern` specifier means the variable that we’re going to declare is already defined and so there’s no need to allocate a new memory space for the variable. Via this specifier we’re telling the compiler that the variable is somewhere in the program and if it checks the ENTIRE codes of all files of that program, it will find the variable and its value.

Note: in C programming, we can’t define the same variable or function two times. That’s a compile time error.

Example: creating external linkage variable in C

Let’s redefine the example at the beginning of this section:

The source code of the `main.c` file:

void printValue(void);
int i = 500;
int main() {

    printValue();
    return  0;
}

The source code of the `secondFile.c` file:

#include <stdio.h>
extern int i;
void printValue(void){

    printf("%d\n",i);
}

As you can see, inside the `secondFile.c` file, we’re trying to access the variable `i` of the `main.c` file. This variable is file-scope and so potentially is accessible from other source-codes.

So in the secondFile.c we re-declared the variable with the specifier `extern` in order to be able to use this variable.

Note: We can’t initialize the re-declared file. The compiler will return an error.

For example: extern int i = 100; //WRONG…

When we re-declare a variable via the specifier `extern` it simply reminds the compiler that the variable already exists and there’s no need to allocate a new memory space to this variable.

Now let’s compile and run the program to see if it works correctly:

Open the Command Prompt and go to the same folder that both files exist. Then run the command below in order to compile the program:

`gcc main.c secondFile.c`

command prompt

As you can see, the file this time compiled correctly, and there’s no error.

Now let’s just run the program to see if it gives us the right output:

command prompt

There it is! The value 500 is accurately printed on the console.

So remember, in order to access the value of a variable in another source-code, that variable:

  • Should have file-scope.
  • The source-code that wants to use the variable should re-declare it via the specifier `extern`.
  • And after that, both the re-declared and the main variable have the access to the same memory-space and so any modification each of these variables does, it will be applied to the same memory-location.

Internal Linkage

By now, we should know that a file-scope variable is potentially accessible from other source codes in other files.

All they need to do is to re-declare the variable with the specifier `extern`.

But sometimes, we have a file-scope variable and we don’t want other source-code files to access the value of this variable or be able to modify its content.

Basically, we don’t want to share the variable.

This is where we can turn the variable’s linkage into internal via the `static` specifier.

This means ONLY the functions in the same file that the variable is defined can access the content of the variable.

Example: creating internal linkage variable in C

#include <stdio.h>
void printValue(void);
static int i = 500;
int main() {

    printValue();
    return  0;
}

void printValue(void){

    printf("%d\n",i);
}

Output:

500

In this example, the variable `i` is defined `static` and so only this file can access the content of the variable.

Note: A constant variable that is declared outside of any function has the internal linkage by default.

No-Linkage

A variable that is declared inside a function or a block has the no-linkage. This means no other functions in the same file or other files can access and modify the content of the variable.

Note: this is the default behavior, but of course we can use pointers to circumvent the behavior, but that’s a different story.

Example: creating no-linkage variable in C

#include <stdio.h>
void printValue(void);

int main() {
    int i = 900;
    printValue();
    return  0;
}

void printValue(void){

    printf("%d\n",i);
}

Output:

error: 'i' undeclared (first use in this function)

printf("%d\n",i);

As you can see, we’ve got an error because of the attempt to access the value of the variable `i` within the body of the function `printValue`. But because the variable `i` is of no-linkage, we couldn’t access the content in the second function and that’s why we’ve got the error.

Functions and Linkage

We’re also able to call functions in other source-code files.

Functions by default are external, which means we can simply call them in other source-codes in order to execute their content.

Unlike variables, though, we don’t need to re-declare a function.

Simply call the function in another file and it will run.

This is exactly what we did in the `external linkage` part.

Functions and Internal Linkage:

Just like variables, via `static` specifier, we can turn a function to be only accessible internally within the file that is declared.

Example: functions and linkage

#include <stdio.h>
static void printValue(void);
int i = 900;
int main() {

    printValue();
    return  0;
}

void printValue(void){

    printf("%d\n",i);
}

In this example, the function `printValue` is declared `static` and so is only accessible within this file.

Any attempt to call the `printValue` function in other source codes will return error.

Leave a Reply