mejdi hrairi
4 min readSep 16, 2020


What happens when you type gcc main.c

So how do we write all this code and computer knows exactly what we want. Well Compilation Process is the one that makes that happen and here is how it works.

First we write some program in C and name it something like main.c.

Now in order to make that program to work we need compile it. Now what in the world does that mean? Simply put; by compiling the program we wrote we actually translate our code that makes sense to us to code that makes sense to our machine. Also known as machine code or binary code. It’s called binary because it consists of only two different values, zeros and ones. Wow!! Mind blown, right? Our computers actually only ‘speak’ binary.

So to translate our code to binary we use compiler. To compile our code we need to run gcc. GCC stands for GNU Compiler Collection and it works with languages like C, C++, Objective-C, Fortran, Ada, and Go. For our example we’ll use C language.

We compile a file by running gcc followed by filename (in our case main.c).

So it looks like this after our command prompt: gcc main.c (take a look at the example bellow).

Now when we do that in return we get back the file named by default a.out which is executable (which means we use that one to run this program we wrote) and when we run it we get our program doing what we want it to do.

Command Line Example

Now let’s take a look at what happens behind the scenes.

Step 1. Preprocessor

When we run gcc main.c, main.c program gets processed by preprocessor. There are three things that preprocessor does:

  • First: it removes all the comments from our program main.c
  • Second: it includes code from header and source file
  • Third: it replaces macros (if there are any that are used in the program) with code.

Step 2. Compiler

The code generated by preprocessor is then given to compiler and compiler generates assembly code from it.

Step 3. Assembler

Since our computer still can not understand assembly code assembler converts assembly code into binary code (the one our machine can actually interpret).

So we are here.

Now what?

Step 4. Linking

Now linker is the one that links all this binary code form our program to libraries and puts it together into one code that we get in a form of executable file (a.out).

But of course we don’t want to have all of our programs be named the same, do we? So we can use -o option with our gcc command that is allowing us to name our executable file whatever we want (like for example my_program).

Naming executable file with gcc -o

Few other options that you can take a look at are

  • -E which runs a C file through the preprocessor and saves the result into another file (in example below it’s 1_preprocessor)
  • -S that generates the assembly code of a C code and saves it in an output file (by default its the same name of the file but with extension .s)
  • -c that compiles a C file but does not link and saves it in an output file(by default its the same name of the file but with extension .o, also called object file)

gcc with different options (-E, -S, -c)

Of course gcc like many other Linux commands has many options that can be used with it but for all that take a look at gcc man page.