Understand the four stages of how a C source file is transformed into an executable file.
The journey of a C source code file from human-readable text to a machine-executable program is a multi-stage process managed by the compiler toolchain. Understanding these stages is vital for effective debugging and optimization. The process, often simplified as 'compilation,' actually consists of four distinct phases. The first stage is **Preprocessing**. The preprocessor handles directives that start with a `#`. It processes lines like `#include` by inserting the contents of the specified header file into the source code. It also handles `#define` directives by substituting macros with their values and resolves conditional compilation directives. The output is a single, expanded C source file. The second stage is **Compilation**. The compiler takes the preprocessed source code and translates it into assembly language specific to the target processor architecture. During this phase, the compiler performs syntax analysis, checks for errors, and carries out various optimizations to make the code more efficient. The resulting assembly code is an intermediate, human-readable representation of the machine instructions. The third stage is **Assembly**. The assembler takes the assembly code generated by the compiler and converts it into machine code, also known as object code. This code consists of binary instructions that the processor can directly understand. The output of this stage is an object file, which typically has a `.o` or `.obj` extension. This file contains the compiled code but is not yet executable because it may reference functions or variables defined in other files or libraries. The final stage is **Linking**. The linker takes one or more object files and links them together with necessary code from standard libraries to produce a single executable file. It resolves symbolic references, such as function calls from your code to library functions like `printf`, by finding their actual locations in memory. Once all references are resolved, the linker generates the final executable program that you can run from your command line.