C/C++ Compilation

Both C and C++ are compiled languages – which means the source code (program) written in C/C++ needs to be “compiled” before it can be executed (run).

C/C++ programs can be compiled to create either of the following forms:

  1. Executable (usually called “binary file”)
  2. Shared library
  3. Static library

what is compilation ? – compilation is a process of translating the human readable, understandable instructions (programs) into machine (i.e., computer) readable, understandable and executable instructions.

 

what are the steps involved in compilation ? – compilation of a C/C++ involves the following steps:

  1. Preprocessing
  2. Compiling
  3. Assembly
  4. Linking

Example Program:

#include 
#define TEXT "Hello, World!"
int main()
{
        /* printing */
        printf(TEXT);
}

On a high-level, command used to complete all the compilation process in one shot (to form an executable), this is what mostly used, rest of the process is taken care by “compiler” itself.

command: gcc hello.c -o hello

Preprocessing:

  • Comments will be removed.
  • “#include <filename>” statements gets replaced with actual contents of the particular file.
  • macros gets replaced with its actual value.

command: gcc -E hello.c -o hello.i

...
extern int pclose (FILE *__stream);
...
# 864 "/usr/include/stdio.h" 3 4
extern int __uflow (FILE *);
extern int __overflow (FILE *, int);
# 879 "/usr/include/stdio.h" 3 4
# 2 "hello.c" 2
...
# 5 "hello.c"
int main()
{
 printf("Hello, World!");
}

Compiling:

  • Compiler translates the “preprocessed” source code to “assembly” code (written in assembly language).

command: gcc -S hello.c -o hello.s

        .file   "hello.c"
        .text
        .section        .rodata
.LC0:
        .string "Hello, World!"
        .text
        .globl  main
        .type   main, @function
main:
.LFB0:
        .cfi_startproc
        pushq   %rbp
        .cfi_def_cfa_offset 16
        .cfi_offset 6, -16
        movq    %rsp, %rbp
        .cfi_def_cfa_register 6
        movl    $.LC0, %edi
        movl    $0, %eax
        call    printf
        movl    $0, %eax
        popq    %rbp
        .cfi_def_cfa 7, 8
        ret
        .cfi_endproc
.LFE0:
        .size   main, .-main
        .ident  "GCC: (GNU) 8.3.1 20191121 (Red Hat 8.3.1-5)"
        .section        .note.GNU-stack,"",@progbits

Assembly:

  • Assembler translates the “assembly” code into “object” code.

command: gcc -c hello.c -o hello.o

...
^@^N^@^@^@^P^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@hello.c^@main^@printf^@^@^@^@^E^@^@^@^@^@^@^@
^@^@^@^E^@^@^@^@^@^@^@^@^@^@^@^O^@^@^@^@^@^@^@^B^@^@^@
^@^@^@üÿÿÿÿÿÿÿ ^@^@^@^@^@^@^@^B^@^@^@^B^@^@^@^@^@^@^@^@^@^@^@^@.symtab^@.strtab^@.shstrtab^@.rela.text^@.data^@.bss^@.rodata^@.comment^@.note.GNU-stack^@.rela.eh_frame^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@ ^@^@^@^A^@^@^@^F^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@@^@^@^@^@^@^@^@^Z^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^A^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^[^@^@^@^D^@^@^@@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@ð^A^@^@^@^@^@^@0^@^@^@^@^@^@^@
...

Linking:

  • Compiler links the “object” code with the standard libraries and/or user defined libraries for the functions that are used in the program (“printf()” in the example)

command: gcc hello.c

Final output is an execute (a.out) file.