top of page

Compilation Process in C++


What is a compilation?

Compilation is a process of converting the source code into the object code.

It is done by help of compiler.

What is compiler?

In computing compiler is a computer program that translate the source code to object code means that translate high level language to low level(machine level) language.

high level language means source code

low level language means machine level means object code

Source code:

In computing Source code is the language or string of words, numbers, letters and symbols that a computer programmer uses. it is also known as human readable programming language.

It is high level programming language which human can understand easily.

Object code:

Object code refers to low level code which is understandable by machine. Object code is generated from source code after going through compiler or other translator. It is in executable machine code format. Object code contains a sequence of machine understandable instructions to which Central Processing Unit understands and executes.

Stage of compilation process:

The following are the phases through which our program passes before being transformed into an executable form:

  • Preprocessor

  • Compiler

  • Assembler

  • Linker

Preprocessor:

Preprocessor are the program that process our source code before the compilation

Preprocessor gives the instruction to the compiler to preprocess the information before the actual compiler.

Preprocessor removes all the commented code from source code and generate extended code.

All of these preprocessor directives begin with a ‘#’ (hash) symbol. The ‘#’ symbol indicates that, whatever statement starts with #, is going to the preprocessor program, and preprocessor program will execute this statement. Examples of some preprocessor directives are: #include, #define, #ifndef etc. Remember that # symbol only provides a path that it will go to the preprocessor, and command such as include is processed by preprocessor program. For example, include will include extra code to your program. We can place these preprocessor directives anywhere in our program.

Ex: g++ -E <file_nam.cpp>

-E option tells the compiler to only preprocess our source code and generate extended code.

The facilities provided by a preprocessor are given below:

1) Macros

2) File Inclusion

3) Conditional Compilation.

4) Other directive

Macros:

A macro is a fragment of code in a program that is given a name.You can define a macro using the #define preprocessor directive. Whenever this name is encountered by the compiler the compiler replaces the name with the actual piece of code.


#include<iostream>
#define max(a,b) (a < b) ? b : a //macro defined here
int main()
{
 int x = 10;
 int y =20;
 int z = max(x,y);
 std :: cout<< x << y << z << std :: endl;
}

File Inclusion:

This type of preprocessor directive tells the compiler to include a file in a source code program.

There are two type of files which can be included by the user in program.

1) Header file or standard file:

This file contains the pre-defined function ,or definition to object like cin, cout.

This file can include as:

Ex: #include<iostream>

#include<string>

<file_name> --> This bracket tells the compiler to look for file in standard directory.

2) User defined files:

When a program becomes very large, it is good practice to divide it into smaller files and include whenever needed. These types of files are user defined files.

These files can be included as:

#include " file_name"

"file_name" --> this " " tells the compiler to look for file in local directory and include whenever needed.

Conditional Compilation:

This directive which help to compile a specific portion of program or to skip compilation of some specific portion of program based on some conditions. This can be done with the help of two preprocessing commands ‘ifdef‘ and ‘endif‘.

#ifdef macro_name

statement1;

statement2;

statement3;

.

.

.

statementN;

Other directive:

#undef Directive: The #undef directive is used to undefine an existing macro.

Ex:

#undef LIMIT

Using this statement will undefine the existing macro LIMIT. After this statement every “#ifdef LIMIT” statement will evaluate to false.

#pragma Directive:

This directive is a special purpose directive and is used to turn on or off some features. This type of directives are compiler-specific, i.e., they vary from compiler to compiler.

Some of the #pragma directives are discussed below:

#pragma startup and #pragma exit: These directives helps us to specify the functions that are needed to run before program startup( before the control passes to main()) and just before program exit (just before the control returns from main()).


#include <bits/stdc++.h>
using namespace std;    
void func1();
void func2();
#pragma startup func1
#pragma exit func2
void func1()
{
    cout << "Inside func1()\n";
} 
void func2()
{
    cout << "Inside func2()\n";
}
int main()
{
    void func1();
    void func2();
    cout << "Inside main()\n";
    return 0;
}

output:

Inside func1()

Inside main()

Inside func2()


Compiler:

The code which is expanded by the preprocessor is passed to the compiler. The compiler converts this code into assembly code. Or we can say that the C++ compiler converts the pre-processed code into assembly code. Generated assembly code extension will be <file_name.s>

Ex: g++ -s <file_name.cpp>

above command only generate the assembly code<file_name.s>.

Because –s option tells the compiler to convert the source code to assembly code only.

Assembler:

The assembly code is converted into object code by using an assembler. The name of the object file generated by the assembler is the same as the source file. The extension of the object file in DOS is '.obj,' and in UNIX, the extension is 'o'. If the name of the source file is 'hello.cpp', then the name of the object file would be 'hello.o'.

Ex: g++ -c <file_name.cpp>

Above command only generate the object code.

Because –c option tells the compiler to only convert the assembly code to object code.

Linker:

Linker is a program which takes all the object files generated by compiler and combine them into a single executable file and also linker is capable to do linking library files.

It perform the process of linking.

Linking is process of collecting and maintaining piece of code and data into a single file.

Linking is performed at both compile time, when the source code is translated into machine code and load time, when the program is loaded into memory by the loader.

There are two type of linking:

Static linking: It is performed during the compilation of source program. Linking is performed before execution in static linking. It takes collection of relocatable object file and command-line argument and generate fully linked object file that can be loaded and run.

Static linker perform two major task:

Symbol resolution – It associates each symbol reference with exactly one symbol definition .Every symbol have predefined task.

Relocation – It relocate code and data section and modify symbol references to the relocated memory location.

The linker copy all library routines used in the program into executable image. As a result, it require more memory space. As it does not require the presence of library on the system when it is run . so, it is faster and more portable. No failure chance and less error chance.

Dynamic linking:

Dynamic linking is performed during the run time. This linking is accomplished by placing the name of a shareable library in the executable image. There is more chances of error and failure chances. It require less memory space as multiple program can share a single copy of the library.

Here we can perform code sharing. it means we are using a same object a number of times in the program. Instead of linking same object again and again into the library, each module share information of a object with other module having same object. The shared library needed in the linking is stored in virtual memory to save RAM. In this linking we can also relocate the code for the smooth running of code but all the code is not relocatable. It fixes the address at run time.

Comments


bottom of page