1.3. Компиляция

Программы на языке C++ следует называть name.cpp, где name заменяется именем вашей программы, а расширение .cpp сообщает компилятору (и вам тоже), что это исходный файл кода, который содержит инструкции на языке программирования C++. Ниже представлена классическая программа на C++ (файл hello.cpp):

#include <iostream>
using namespace std;

int main()
{
    cout<<"Hello World";
    return 0;
}

Перед тем как ее выполнить, данный код перевести в машинный. Процесс перевод состоит их 3 частей:

  1. Работа препроцессора
  2. Компиляция
  3. Линковка

Препроцессор

Язык препроцессора – это специальный язык программирования, встроенный в C++.

  • Препроцессор работает с кодом на C++ как с текстом.
  • Команды языка препроцессора называют директивами. все директивы начинаются со знака #.
  • Директива #include позволяет подключать заголовочные файлы к файлам кода.
    • #include <foo.h> — библиотечный заголовочный файл,
    • #include "bar.h" — локальный заголовочный файл.
  • Препроцессор заменяет директиву #include "bar.h" на содержимое файла bar.h.

Компиляция

Работа компилятора состоит из двух этапов:

  • Проверка программы на соответствие правилам языка C++ (проверка синтаксиса). Если она будет неудачной, то компилятор выдаст сообщения об ошибках, которые нужно будет исправить.
  • Конвертация каждого исходного файла с кодом в объектный файл на машинном языке. Объектные файлы, как правило, имеют названия name.o или name.obj, где name должно быть такое же как и имя вашего исходного файла .cpp. Если ваша программа состоит из 3-х файлов .cpp, то компилятор сгенерирует 3 объектных файла.

Линковка

На этом этапе все объектные файлы объединяются в один исполняемый (или библиотечный) файл. При этом происходит подстановка адресов функций в места их вызова. По каждому объектному файлу строится таблица всех функций, которые в нём определены. На этапе компоновки важно, что каждая функция имеет уникальное имя. В C++ может быть две функции с одним именем, но разными параметрами. Имена функций искажаются (mangle) таким образом, что в их имени кодируются их параметры. Например, компилятор GCC превратит следующую функцию: void foo (int , double ) {} в _Z3fooid. По каждому объектному файлу строится таблица всех функций, которые в нём определены.

Точка входа — функция, вызываемая при запуске программы. По умолчанию — это функция main. Она может быть как без параметров так и с параметрами командной строки. Следующие варианты допустимы:

int main() 
{ 
    return 0; 
}
int main(int argc , char** argv) 
{ 
    return 0; 
}

Данная процедура характерна как для программ с один файлом так и и программ разбитым на несколько файлов: Процесс копиляции