
- C - Home
- C - Overview
- C - Features
- C - History
- C - Standards
- C - Environment Setup
- C - Program Structure
- C - Hello World
- C - Compilation Process
- C - Comments
- C - Basic Syntax
- C - User Input
- C - printf Function
- C - Format Specifiers
- Lexical Elements in C
- C - Tokens
- C - Keywords
- C - Identifiers
- Variables and Constants
- C - Variables
- C - Constants
- C - Const Qualifier
- C - Linkage
- Data Types and Type Conversions
- C - Data Types
- C - Literals
- C - Escape sequences
- C - Booleans
- C - Integer Promotions
- C - Character Arithmetic
- C - Type Conversion
- C - Type Casting
- Operators in C
- C - Operators
- C - Arithmetic Operators
- C - Unary Operators
- C - Relational Operators
- C - Logical Operators
- C - Bitwise Operators
- C - Assignment Operators
- C - Increment and Decrement Operators
- C - Ternary Operator
- C - sizeof Operator
- C - Operator Precedence
- C - Miscellaneous Operators
- Decision Making & Control Statements
- C - Decision Making
- C - if statement
- C - if...else statement
- C - if...else if Ladder
- C - Nested if statements
- C - Switch statement
- C - Nested switch statements
- C - Switch Case Using Range
- Loops in C
- C - Loops
- C - For Loop
- C - While Loop
- C - Do...while Loop
- C - For Loop vs While Loop
- C - Nested Loop
- C - Infinite Loop
- C - Break Statement
- C - Continue Statement
- C - Goto Statement
- Functions in C
- C - Functions
- C - Function Prototype
- C - Main Function
- C - Function call by Value
- C - Function call by reference
- C - Nested Functions
- C - Variadic Functions
- C - User-Defined Functions
- C - Callback Function
- C - Return Statement
- C - Recursion
- C - Predefined Identifier __func__
- Scope Rules in C
- C - Scope Rules
- C - Static Variables
- C - Global Variables
- Arrays in C
- C - Arrays
- C - Properties of Array
- C - Multi-Dimensional Arrays
- C - Passing Arrays to Function
- C - Return Array from Function
- C - Variable Length Arrays
- C - Dynamic Arrays
- Strings in C
- C - Strings
- C - Array of Strings
- C - Character Arrays
- C - Special Characters
- Structures and Unions in C
- C - Structures
- C - Structures and Functions
- C - Arrays of Structures
- C - Self-Referential Structures
- C - Dot (.) Operator
- C - Lookup Tables
- C - Enumeration (or enum)
- C - Structure Padding and Packing
- C - Nested Structures
- C - Anonymous Structure and Union
- C - Unions
- C - Bit Fields
- C - Typedef
- Pointers in C
- C - Pointers
- C - Pointers and Arrays
- C - Applications of Pointers
- C - Pointer Arithmetics
- C - Array of Pointers
- C - Pointer to Pointer
- C - Function Pointers
- C - Array of Function Pointers
- C - Passing Pointers to Functions
- C - Return Pointer from Functions
- C - Pointer to an Array
- C - Pointers vs. Multi-dimensional Arrays
- C - Character Pointers and Functions
- C - NULL Pointer
- C - void Pointer
- C - Const Pointers & Pointer to Const
- C - Dangling Pointers
- C - Dereference Pointer
- C - Near, Far and Huge Pointers
- C - Restrict Keyword
- C - Pointers to Structures
- C - Chain of Pointers
- C - Pointer vs Array
- C - Initialization of Pointer Arrays
- Storage Classes and Qualifiers
- C - Storage Classes
- Memory Management in C
- C - Memory Management
- C - Memory Address
- Preprocessors in C
- C - Preprocessors
- C - Pragmas
- C - Preprocessor Operators
- File Handling in C
- C - File I/O (File Handling)
- C - Input & Output
- Constants and Literals in C
- C - Macros
- C - Header Files
- Miscellaneous Topics
- C - Error Handling
- C - Variable Arguments
- C - Command Execution
- C - Math Functions
- C - Static Keyword
- C - Random Number Generation
- C - Command Line Arguments
- C Programming Resources
- C - Questions & Answers
- C - Quick Guide
- C - Cheat Sheet
- C - Useful Resources
- C - Discussion
- C Online Compiler
C - Internal and External Linkage
In C, linkage is a concept that explains whether or not names or identifiers can refer to the same entity throughout the entire program or a single translation unit. It may sound similar to program scope but it is not so. To understand this concept better, let us dig deeper into the compilation process.
Before learning the concept of linkage in C, we first need to understand what a translation unit is.
What is a Translation Unit?
A translation unit is a file that has 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 objects.
What is Linkage?
Assume there is a C program with many source code files. Each source file is compiled sequentially. In the compilation process, the last stage is linking, where multiple machine code files are used to produce an executable object code. It is handled by a program called linker.
Linkage is a property that describes how variables should be linked by the linker.
Variable Linkage in C
In C, the linkage can control whether a variable can be used only in the file where it is declared or it can also be used in other files of the program.
Linkage tells us if a variable's name is limited to one file or can be shared across multiple files, helping us manage how variables are connected in a program.
Types of Linkage in C
There are two types of Linkage in C −
- Internal Linkage
- External Linkage
Let's understand these two concepts in detail.
Internal Linkage
Internal linkage refers to everything only in the scope of a translation unit. An identifier that implements internal linkage is not accessible outside the translation unit in which it is declared. So, an identifier with internal linkage can be accessed only within the same file where it is declared.
Internal Linkage is implemented using the static keyword, and its value is stored in RAM (either in the initialized or uninitialized).
Let's understand it through the following example. Let's consider a source file items.c (identifier) −
#include <stdio.h> // Variable with internal linkage Static int items = 10;
The above code implements static linkage on identifier items.
Let's consider another source file display.c which is located in the same translation unit.
#include <stdio.h> #include "items.c" int main(){ printf("total item is: %d", items); return 0; }
Following is the output of the above code after executing the display.c −
total item is: 10
Suppose display.c is located in a different translation unit (meaning we are not including the items.c using #include). Then it gives the error "Each undeclared identifier is reported only once for each function it appears in."
External Linkage
An identifier implementing external linkage exists beyond a particular translation unit and is accessible throughout the entire program, which is the combination of all translation units (or object files). It is the default linkage for globally scoped variables (without static) and functions.
The extern keyword is used to implement external linkage. When we use the 'extern' keyword, we tell the compiler that the variable is defined in another file. Thus, the declaration of an external identifier doesn't use any memory space.
Extern identifiers are stored in RAM's data (initialized/uninitialized) or code (text) segments.
Let's take an example to understand the concept better. Consider a source file: items.c (identifier). In the internal linkage we used the static keyword; here we create a source file without the extern keyword.
#include <stdio.h> // Variable with internal linkage int items = 10;
As the variable items is declared globally, it is accessible to all the translational units. Now, consider the file display.c is in the different translational unit −
#include <stdio.h> // tells the compiler that the variable // have external linkage extern int items; int main(){ printf("total item is: %d", items); return 0; }
Here is the output of the above code after executing the display.c −
total item is: 10
Conclusion
Linkage in C defines whether variables and functions can be accessed only within a single file or across multiple files of a program. By using internal linkage (static) and external linkage (extern), we can control the scope and accessibility of identifiers. It ensures better program structure and modularity.