Introduction to Building C++ Applications
Programming languages differ by their program execution model; the most common are interpreted and compiled languages. Compilers translate source code into machine code, which a computer can run without intermediary support systems. Interpreted language code, on the other hand, requires support systems, interpreters, and the virtual environment to work.
C++ is a compiled language, which makes programs run faster than their interpreted counterparts. While C++ programs should be compiled for each platform, interpreted programs can operate cross-platform.
We are going to discuss the details of a program-building process, starting with the phases of processing the source code – done by the compiler- and ending with the details of the executable file (the compiler's output). We will also learn why a program built for one platform...
Technical requirements
The g++ compiler with the option -std=c++2a is used to compile the examples throughout the chapter. You can find the source files used in this chapter at https://github.com/PacktPublishing/Expert-CPP .
Introduction to C++20
C++ has evolved over the years and now it has a brand-new version, C++20. Since C++11, the C++ standard has grown the language feature set tremendously. Let's look at notable features in the new C++20 standard.
Concepts
Concepts are a major feature in C++20 that provides a set of requirements for types. The basic idea behind concepts is the compile-time validation of template arguments. For example, to specify that the template argument must have a default constructor, we use the default_constructible concept in the following way:
template <default_constructible T>
void make_T() { return T(); }
In the preceding code, we missed the typename keyword. Instead, we set a concept that describes the...
Building and running programs
You can use any text editor to write code, because, ultimately, code is just text. To write code, you are free to choose between simple text editors such as Vim, or an advanced integrated development environment
Understanding preprocessing
For example, the following code will be changed before the compiler starts to compile it:
#define NUMBER 41
int main() {
int a = NUMBER + 1;
return 0;
}
Everything that is defined using the #define directive is called a macro. After preprocessing, the compiler gets the transformed source in this form:
int main() {
int a = 41 ...
Understanding Compiling
The C++ compilation process consists of several phases. Some of the phases are intended to analyze the source code, and others generate and optimize the target machine code. The following diagram shows the phases of compilation:

Let's look at each of these phases in detail.
Tokenization
The analysis phase of the compiler aims to split the source code into small units called tokens. A token may be a word or just a single symbol, such as = (the equals sign). A token is the smallest unit of the source code that carries meaningful value for the compiler. For example, the expression int a = 42; will be divided into the tokens int, a, =, 42, and ;. The expression isn't just split by spaces, because...
Introducing Linking
The compiler outputs an object file for each compilation unit. In the previous example, we had three .cpp files and the compiler produced three object files. The task of the linker is to combine these object files together into a single object file. Combining files together results in relative address changes; for example, if the linker puts the rect.o file after main.o, the starting address of rect.o becomes 0x04 instead of the previous value of 0x00:
code:
0x00 main
0x01 Rect r;
0x02 _Rect_init_(&r, 3.1, 4.05);
0x03 printf("%d\n", _Rect_get_area(&r));
0x04 _Rect_init_
0x05 side1_ = s1
0x06 side2_ = s2
0x07 return
0x08 _Rect_get_area_
0x09 register = side1_
0x0A reg_multiply side2_
0x0B return
information (symbol table):
main: 0x00
_Rect_init_: 0x04
printf: ????
_Rect_get_area_: 0x08
_Rect_init_: 0x04
_Rect_get_area_...
Summary
In this chapter, we touched on a few of the many new features of C++20 and are now ready to dive deeper into the language. We discussed the process of building a C++ application and its compilation phases. This includes analyzing the code to detect syntactical and grammatical errors, generating intermediate code to make optimizations, and finally, generating the object file that will be linked together with other generated object files to form the final executable file.
In the next chapter, we will learn about C++ data types, arrays, and pointers. We will also gain an understanding of what pointers are and look at low-level details of conditionals.
Questions
- What is the difference between a compiler and an interpreter?
- List the program compilation phases.
- What does the preprocessor do?
- What are the tasks of the linker?
- What is the difference between statically and dynamically linked libraries?
Further reading
For more information, refer to Advanced C and C++ Compiling at https://www.amazon.com/Advanced-C-Compiling-Milan-Stevanovic/dp/1430266678/
LLVM Essentials, https://www.packtpub.com/application-development/llvm-essentials