The compilation process in C transforms human-readable source code into machine-executable programs, enabling computers to understand and execute instructions written in C. This process is essential for translating high-level programming constructs into binary code that the hardware can process.
The process is divided into several key stages, each playing a crucial role:
Each stage of this pipeline ensures the code is optimized, error-checked, and linked correctly to external dependencies. Understanding this process provides insights into how C programs are executed, making it easier to debug, optimize, and work effectively in the development process.
The compilation process in C involves several steps that convert human-readable C code into machine-readable code. The process is broken down into the following stages:
The first step of the compilation process is preprocessing, which involves preparing the C source code for compilation by performing various operations like file inclusion, macro substitution, and conditional compilation.
Tasks performed during preprocessing:
Example:
#include
#define MAX 100
int main() {
printf(“Max value is %d”, MAX);
return 0;
}
After preprocessing, the code will look like:
int main() {
printf(“Max value is %d”, 100);
return 0;
}
The result of preprocessing is called the preprocessed source code.
During this stage, the preprocessed C source code is compiled into assembly code specific to the target architecture. The compiler translates the high-level C code into a lower-level language that the machine can understand.
Example: The code might be transformed into assembly language:
mov eax, 100
call printf
In this step, the assembly code produced by the compiler is translated into machine code (binary code) by the assembler. The result is an object file (with .o or .obj extension).
The assembler converts human-readable assembly instructions into machine instructions that can be executed by the processor.
Example: The assembly code will be converted into machine code like:
01010100 01101001 11001000
The final step is linking, where one or more object files generated by the assembler are combined to form the executable program. The linker also handles the integration of external libraries and ensures that function calls and variables are properly connected.
There are two types of linking:
The linker resolves symbols and addresses for function calls, variables, and external libraries. The output of this stage is the final executable file (usually .exe on Windows or no extension on Unix-based systems).
After linking, the final executable can be run. At this point, the program has been fully translated into machine code and can be executed by the operating system.
Steps in summary:
Diagram of Compilation Process:
Source Code (.c) –> Preprocessor –> Preprocessed Code
|
v
Compiler –> Assembly Code (.s)
|
v
Assembler –> Object Code (.o)
|
v
Linker –> Executable File (.exe or no extension)
|
v
Program Execution
Indian Institute of Embedded Systems – IIES