Какую задачу решает линкер (компоновщик) в процессе сборки C++ программы?

«Какую задачу решает линкер (компоновщик) в процессе сборки C++ программы?» — вопрос из категории C++ Core, который задают на 25% собеседований C/C++ Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Линкер — это программа, которая принимает на вход один или несколько объектных файлов (.o, .obj), полученных от компилятора, и библиотеки, а на выходе создаёт единый исполняемый файл или библиотеку. Его ключевая задача — разрешение внешних ссылок.

Конкретные функции линкера:

  1. Связывание (Resolution): Объектный файл содержит «ссылки» на имена функций и глобальных переменных, определённых в других файлах или библиотеках (например, cout из стандартной библиотеки). Линкер находит эти определения и подставляет правильные адреса.
  2. Объединение секций: Код из разных .o файлов собирается в секцию .text, данные — в .data или .bss и т.д.
  3. Распределение адресов: Назначает окончательные виртуальные адреса для всех частей программы.

Типичные ошибки линкера:

  • undefined reference to 'symbol': Линкер не нашёл определение для объявленного символа. Причина: забыли подключить объектный файл или библиотеку, опечатка в имени.
  • multiple definition of 'symbol': Обнаружено более одного определения одного символа. Частая причина — определение функции в заголовочном файле без inline или static, который включили в несколько .cpp-файлов.

Пример:

// math_utils.h
#pragma once
extern int global_counter; // Объявление глобальной переменной
int add(int a, int b);     // Объявление функции

// math_utils.cpp
#include "math_utils.h"
int global_counter = 0;    // Определение глобальной переменной
int add(int a, int b) {    // Определение функции
    return a + b;
}

// main.cpp
#include "math_utils.h"
#include <iostream>
int main() {
    global_counter++;
    std::cout << add(5, 3); // Вызов функции, определённой в другом файле
    return 0;
}

Линкер соберёт main.o и math_utils.o, связав вызов add и обращение к global_counter с их определениями.