C Programming - Beginner to Brilliance / Introduction to C

Compilation & Execution Process

💡 What does “Compilation” mean?

When you write a program in C, the computer doesn’t understand that human-readable code directly. It only understands machine code (0s and 1s).

So we need a compiler that translates our .c file into machine-readable format (executable file).

Think of it like:

📝 Your C code → 🗣️ Translator (Compiler) → 🖥️ Computer-readable code


🛤️ Step-by-Step Compilation Flow:


✅ Step 1: Preprocessing

📌 What happens?

  • All lines starting with # (like #include, #define) are handled here.

  • It’s like preparing all raw materials before starting construction.

🧱 Examples:

  • Replaces #define PI 3.14 with 3.14

  • Adds contents of #include <stdio.h> at the top

🔧 Tool Used Internally: cpp (C PreProcessor)


✅ Step 2: Compilation

📌 What happens?

  • The preprocessed .i file is converted to Assembly language (.s file).

  • Assembly is low-level but still human-readable (like a bridge between C and binary).

🧱 Why this step matters?

  • Compiler checks for syntax errors (missing semicolons, wrong types, etc.)

  • Generates machine instructions for each line of code

🔧 Tool Used Internally: cc1 (GCC Compiler core)


✅ Step 3: Assembly

📌 What happens?

  • Converts .s Assembly code into object code (machine code) but not complete yet.

🧱 Object files contain compiled code for each function, but without connecting to library functions like printf.

🔧 Tool Used Internally: as (Assembler)


✅ Step 4: Linking

📌 What happens?

  • Links your .o file with library files (like code for printf, scanf, etc.)

  • Produces a complete executable file that can run on the system

🧱 Library Linking:

  • Every time you use printf(), it doesn’t exist in your code

  • It’s part of the C standard library, so linker connects your code to those definitions

🔧 Tool Used Internally: ld (Linker)


🧪 Optional Step 5: Execution

📌 What happens?

  • You run the final executable using your OS

  • OS loads your program into memory and the CPU executes the instructions

🧱 You finally see output like:

Hello, World!

🧱 GCC Compilation Stages and Output Files

When you compile C code with gcc, it goes through 4 major steps:

Step

Name

File Extension

What It Contains

1

Preprocessing

program.i

Expanded source code (macros, includes)

2

Compilation

program.s

Assembly code

3

Assembling

program.o

Machine code (object file)

4

Linking

a.out (default) or program.exe

Final executable


🔍 Why You Don’t See These Files by Default

By default, when you run:

gcc program.c

GCC:

  • Internally goes through all 4 steps

  • Deletes intermediate files (.i, .s, .o)

  • Only keeps the final output: a.out (the executable)

You only see a.out unless you instruct GCC to stop at a specific step or keep other files.


📂 How to Generate and See These Files:

Purpose

Command

Output File

Only Preprocess

gcc -E program.c -o program.i

program.i

Only Compile to Assembly

gcc -S program.c -o program.s

program.s

Only Assemble to Object

gcc -c program.c -o program.o

program.o

Compile Full and Name It

gcc program.c -o program

program (exe)


🧠 Extra Tip: View All Steps Verbosely

gcc -v program.c

This shows each internal stage of compilation.


🧪 Real Example using GCC/GNU Complier

GCC (GNU Compiler Collection) is a powerful open-source compiler developed by the GNU Project. It is widely used to compile programs written in C, C++, and other languages

Let’s say you have this file hello.c:

#include <stdio.h>

int main() {
    printf("Hello, C!\\n");
    return 0;
}

🔧 You compile using:

gcc hello.c -o hello

👉 This command internally does:

cpp hello.c → hello.i       # Preprocess
cc1 hello.i → hello.s       # Compile
as hello.s → hello.o        # Assemble
ld hello.o → hello (exe)    # Link

Then you run it:

./hello
Hello, C!

❓ Why is this Important?

Understanding the compilation process helps you:

🧠 Concept

🧾 Benefit

🐞 Debugging

You can understand at which stage the error happened

💡 Optimization

You can analyze object files and assembly for performance

🔗 Linking Errors

Understand why you get errors like "undefined reference to main"

🔍 Tool Use

Helps with static analysis, memory debugging, and build tools

🧱 Large Projects

Crucial for writing Makefile, managing modular code


💬 Final Tips

  • Use E, S, c flags with gcc to stop at different stages:

    gcc -E hello.c -o hello.i   # Preprocess only
    gcc -S hello.c -o hello.s   # Compile only
    gcc -c hello.c -o hello.o   # Assemble only
  • View assembly code using:

    gcc -S hello.c
    cat hello.s