Summary
This lesson explains what a program is and what a compiler does: the machine only executes elementary operations on numbers in memory, and source code must be translated into machine code before it can run. With a two-file program it follows the three stages of that translation in C++ (preprocessing, compilation and linking), and it distinguishes what happens when compiling from what happens when running, with an error of each kind. It compares compiled languages with interpreted ones, summarizes the history of C++ up to the C++23 and C++26 standards, and specifies which C++ this course teaches.
Learning objectives
- Explain, with a diagram, the path from a source file to an executable: preprocessing, compilation and linking, with what goes into and what comes out of each stage.
- Classify an event as belonging to compilation, linking or execution, such as a syntax error, a missing function or a division by zero.
- Compare a compiled language with an interpreted one according to when errors are detected and what the programmer sees of the machine.
- Place the standards of the language in time and explain why the course uses C++23.
What a program is
A program is a sequence of instructions that a machine can execute to transform some data into some results. In the previous lesson, From the problem to the algorithm, we saw that before the program comes the algorithm, the method that solves the problem, written for a person to follow. The program is that same method written for a machine, which understands neither sentences nor intentions, only elementary commands: copy a number from one place in memory to another, add two numbers, compare them, jump to another instruction depending on the result.
The computer’s memory is a long row of numbered cells, each holding a number from 0 to 255 (a byte). Everything the machine handles is encoded there as numbers: the data and also the instructions themselves. If this is so, an executable program is a sequence of numbers that the processor interprets as commands, machine code, and it depends on the processor: those of the x86-64 family, common in desktop computers, and ARM processors, common in phones and in recent Macs, do not understand the same numbers.
Nobody writes in machine code today. One writes in a high-level language, such as C++, whose instructions resemble mathematical notation, in a text file called source code (or simply the source). It follows that a translator is needed to produce, from the source, the equivalent machine code: in C++, the compiler.
This is a complete program in C++. There is no need to understand it yet: each of its lines will be explained in lesson 1.5. It is enough to see that it is text, that it can be read, and that below it appears what it printed when run.
// Explained line by line in lesson 1.5.#include <print>int main(){ std::println("Hello, world"); std::println("2 + 3 = {}", 2 + 3);}Hello, world2 + 3 = 5To see the other end of the translation, consider a function that only adds two integers (functions will be studied in unit 5). It is not a complete program, because it lacks main, the point where execution begins, but the compiler can translate it on its own.
int add(int a, int b){ return a + b;}The program objdump shows the machine code that GCC 15 produced for it on an x86-64 computer with Linux: on each line, the position of the instruction, its bytes in hexadecimal and its readable name.
$ g++ -std=c++23 -O1 -c add.cpp$ objdump -d add.o0000000000000000 <_Z3addii>: 0: f3 0f 1e fa endbr64 4: 8d 04 37 lea (%rdi,%rsi,1),%eax 7: c3 retThe integer addition was reduced to eight bytes. The first instruction, endbr64, is a security marker that computes nothing; the second, lea, adds the two numbers that the function received in two processor registers (%rdi and %rsi) and leaves the result in a third (%eax); the third, ret, returns to the point from which the function was called. The name _Z3addii is the way the compiler encodes “function add with two int parameters”.
Two observations follow from the example. First: machine code keeps neither the names a and b, nor the indentation, nor the comments; all of that existed for whoever reads the source, and the compiler used it to decide which instructions to write. Second: what the C++ programmer writes is translated into a few instructions and without intermediaries; that closeness to the machine is the reason for the efficiency of C++ and, as the course will show, also for some of its dangers.
Loading the content…
Completed
Sign in to save your progress