Как заголовочные файлы C++ работают?

То, когда я включаю некоторую функцию от заголовочного файла в программе C++, делает весь код заголовочного файла, копируются в заключительный исполняемый файл, или только машинный код для определенной функции сгенерирован. Например, если я звоню std::sort от <algorithm> заголовок в C++, машинный код, сгенерированный только для вида () функция или для всего <algorithm> заголовочный файл.

Я думаю, что подобный вопрос существует где-нибудь на Переполнении стека, но я старался изо всех сил находить его (я посмотрел на него однажды, но потерял ссылку). Если бы можно указать на меня, к которому, это было бы замечательно.

8
задан user225312 16 May 2010 в 14:57
поделиться

4 ответа

Здесь вы смешиваете две разные проблемы:

  1. Заголовочные файлы, обрабатываемые препроцессором
  2. Выборочное связывание кода компоновщиком C ++

Заголовочные файлы

Они просто дословно копируются препроцессором в место, которое включает их. Весь код алгоритма копируется в файл .cpp , когда вы #include .

Выборочное связывание

Большинство современных компоновщиков не связывают функции, которые не вызываются в вашем приложении. Т.е. напишите функцию foo и никогда не вызывайте ее - ее код не попадет в исполняемый файл. Итак, если вы #include и используете только sort , вот что произойдет:

  • Препроцессор поместит весь файл алгоритм в ваш исходный файл
  • Вы вызываете только sort
  • Связанный анализирует это и только добавляет источник sort (и функции, которые он вызывает, если они есть) к исполняемому файлу. Код других алгоритмов не добавляется

Тем не менее, шаблоны C ++ еще больше усложняют дело. Это сложный вопрос, который нужно объяснить здесь, но в двух словах - шаблоны расширяются компилятором для всех типов, которые вы фактически используете. Таким образом, если есть вектор из int и вектор из string , компилятор сгенерирует две копии всего кода для вектор в вашем коде. Поскольку вы его используете (иначе компилятор не сгенерировал бы его), компоновщик также помещает его в исполняемый файл.

11
ответ дан 5 December 2019 в 11:23
поделиться

Фактически, весь файл копируется в файл .cpp, и это зависит от компилятора / компоновщика, выбирает ли он только «необходимые» функции, или все они.

В общем, упрощенное резюме:

  • конфигурация отладки означает компиляцию всех не шаблонных функций,
  • конфигурация выпуска удаляет все ненужные функции.

Кроме того, это зависит от атрибутов -> функция, объявленная для экспорта, никогда не будет удалена. С другой стороны, варианты функции шаблона "генерируются" при использовании, поэтому компилируются только те, которые вы явно используете.

РЕДАКТИРОВАТЬ: код файла заголовка не создается, но в большинстве случаев написан вручную.

3
ответ дан 5 December 2019 в 11:23
поделиться

Если вы #include заголовочный файл в исходный код, он действует так, как если бы текст в этом заголовке был написан вместо директива препроцессора #include .

Обычно заголовки содержат объявления, то есть информацию о том, что находится внутри библиотеки. Таким образом, компилятор позволяет вам вызывать объекты, код которых существует вне текущего модуля компиляции (например, файл .cpp, из которого вы включаете заголовок). Когда программа связана с исполняемым файлом, который вы можете запустить, компоновщик решает, что включить, обычно в зависимости от того, что ваша программа фактически использует. Библиотеки также могут быть связаны динамически, что означает, что исполняемый файл фактически не включает код библиотеки, но библиотека подключается во время выполнения.

1
ответ дан 5 December 2019 в 11:23
поделиться

Это зависит от компилятора. Большинство компиляторов сегодня проводят анализ потока, чтобы исключить невызванные функции. http://en.wikipedia.org/wiki/Data-flow_analysis

0
ответ дан 5 December 2019 в 11:23
поделиться
Другие вопросы по тегам:

Похожие вопросы: