Что такое «pch.h» и почему его нужно включать в качестве первого файла заголовка?
Что такое «pch.h»? Почему его нужно включить в качестве первого файла заголовка?
1 ответ
В компьютерном программировании предварительно скомпилированный заголовок — это файл заголовка (C или C ++), который компилируется в промежуточную форму, которая быстрее обрабатывается для компилятора. Использование предварительно скомпилированных заголовков может значительно сократить время компиляции, особенно при применении к файлам заголовков большого размера, файлам заголовков, которые включают множество других файлов заголовков, или файлам заголовков, которые включены во многие единицы перевода.
Чтобы сократить время компиляции, некоторые компиляторы позволяют компилировать файлы заголовков в форму, которая быстрее обрабатывается компилятором. Эта промежуточная форма известна как предварительно скомпилированный заголовок и обычно хранится в файле с расширением .pch или аналогичным, например .gch в Коллекции компиляторов GNU.
Что такое «pch.h» и почему его нужно включать в качестве первого заголовочного файла?
Что такое «пч.ч»? Почему его нужно включать в качестве первого заголовочного файла?
![]()
In computer programming, a precompiled header is a (C or C++) header file that is compiled into an intermediate form that is faster to process for the compiler. Usage of precompiled headers may significantly reduce compilation time, especially when applied to large header files, header files that include many other header files, or header files that are included in many translation units.
To reduce compilation times, some compilers allow header files to be compiled into a form that is faster for the compiler to process. This intermediate form is known as a precompiled header, and is commonly held in a file named with the extension .pch or similar, such as .gch under the GNU Compiler Collection.
Файлы предкомпилированных заголовков
При создании проекта в Visual Studio в pch.h проект добавляется предварительно скомпилированный файл заголовка. (В Visual Studio 2017 и более ранних версиях файл был вызван stdafx.h .) Цель файла — ускорить процесс сборки. Здесь следует включить любые стабильные файлы заголовков, например заголовки стандартной библиотеки, такие как <vector> . Предкомпилированный заголовок компилируется только в том случае, если он или какие-либо содержащиеся в нем файлы были изменены. Если изменения вносятся только в исходный код проекта, при сборке будет пропущена компиляция для предкомпилированного заголовка.
Параметры компилятора для предварительно скомпилированных заголовков. /Y На страницах свойств проекта параметры находятся в разделе Configuration PropertiesC>/C++>Precompiled Headers. Можно не использовать предкомпилированные заголовки, а также указать имя файла заголовка и путь к выходному файлу.
Настраиваемый предварительно скомпилированный код
Для больших проектов, для которых требуется значительное время, может потребоваться создать настраиваемые предварительно скомпилированные файлы. Компиляторы Microsoft C и C++ содержат параметры для предварительной компиляции любого кода C или C++, включая встроенный код. С помощью этой функции производительности можно скомпилировать стабильный текст кода, сохранить скомпилированное состояние кода в файле и во время последующих компиляций объединить предварительно скомпилированный код с кодом, который все еще находится в стадии разработки. Каждая более поздняя компиляция выполняется быстрее, так как стабильный код не требует повторной компиляции.
Когда следует предварительно скомпилировать исходный код
Предварительно скомпилированный код полезен во время цикла разработки, чтобы сократить время компиляции, особенно если:
Всегда используется большой текст кода, в который редко вносятся изменения.
Программа состоит из нескольких модулей, каждый из которых использует стандартный набор включаемых файлов, а также одни и те же параметры компиляции. В этом случае все включаемые файлы можно предварительно скомпилировать в один предкомпилированный заголовок.
Первая компиляция (которая создает предварительно скомпилированный файл заголовка) занимает немного больше времени, чем последующие компиляции. Последующие компиляции могут выполняться быстрее, включая предварительно скомпилированный код.
Можно предварительно скомпилировать программы C и C++. В программировании на C++ часто используется разделение сведений об интерфейсе класса на файлы заголовков. Впоследствии эти файлы заголовков можно будет включать в программы, использующие класс. Предварительная компиляция этих заголовков позволяет сократить время, затрачиваемое программой на компиляцию.
Несмотря на то, что для каждого исходного файла можно использовать только один предварительно скомпилированный заголовок ( .pch файл), в проекте можно использовать несколько .pch файлов.
Два варианта для предварительной компиляции кода
Вы можете предварительно скомпилировать любой код C или C++; Вы не ограничиваетесь предварительной компиляцией только файлов заголовков.
Для предварительной компиляции требуется планирование, но при предварительной компиляции исходного кода, отличного от простых файлов заголовков, обеспечивается значительно более быстрая компиляция.
Предварительная компиляция кода рекомендуется, когда известно, что исходные файлы используют общие наборы файлов заголовков, но не содержат их в том же порядке, или если требуется включить исходный код в предварительную компиляцию.
Параметры предварительно скомпилированного заголовка: /Yc (создать файл предварительно скомпилированного заголовка) и /Yu (использовать файл предварительно скомпилированного заголовка).) Используется /Yc для создания предварительно скомпилированного заголовка. При использовании с необязательным hdrstop pragma /Yc позволяет предварительно скомпилировать файлы заголовков и исходный код. Выберите /Yu для использования существующего предварительно скомпилированного заголовка в существующей компиляции. С параметрами /Yc и /Yu параметрами можно также /Fp указать альтернативное имя предкомпилированного заголовка.
Справочные статьи о параметрах /Yu компилятора и /Yc о том, как получить доступ к этим функциям в среде разработки.
Предварительно скомпилированные правила согласованности заголовков
Так как PCH-файлы содержат сведения о среде компьютера и адресе памяти о программе, следует использовать только PCH-файл на компьютере, на котором он был создан.
Правила согласованности для использования предварительно скомпилированных заголовков для каждого файла
Параметр /Yu компилятора позволяет указать, какой PCH-файл следует использовать.
При использовании PCH-файла компилятор предполагает ту же среду компиляции (которая использует согласованные параметры компилятора, pragmas и т. д.), которая действует при создании PCH-файла, если не указано иное. Если компилятор обнаруживает несогласованность, он выдает предупреждение и по возможности определяет несогласованность. Такие предупреждения не обязательно указывают на проблему с файлом PCH. Они просто предупреждают о возможных конфликтах. Требования к согласованности для файлов PCH описаны в следующих разделах.
Согласованность параметров компилятора
Следующие параметры компилятора могут вызвать предупреждение о несогласованности при использовании файла PCH:
Макросы, созданные с помощью параметра препроцессора ( /D ), должны совпадать между компиляцией, создающей PCH-файл и текущую компиляцию. Состояние определенных констант не проверяется, но непредсказуемые результаты могут произойти при изменении этих макросов.
PCH-файлы не работают с параметрами и /EP параметрами /E .
PCH-файлы должны создаваться с помощью параметра «Создать сведения о просмотре» ( /FR ) или параметра «Исключить локальные переменные() перед /Fr последующими компиляциями, которые используют PCH-файл, могут использовать эти параметры.
C 7.0-compatible ( /Z7 )
Если этот параметр действует при создании PCH-файла, последующие компиляции, использующие PCH-файл, могут использовать сведения об отладке.
Если параметр C 7.0-Compatible ( /Z7 ) не действует при создании PCH-файла, последующие компиляции, использующие PCH-файл и /Z7 запускающие предупреждение. Сведения об отладке помещаются в текущий .obj файл, а локальные символы, определенные в PCH-файле, недоступны отладчику.
Включение согласованности пути
PCH-файл не содержит сведения о пути включения заголовка, который был фактическим при его создании. При использовании PCH-файла компилятор всегда использует путь включения заголовка, указанный в текущей компиляции.
Согласованность исходного файла
При указании параметра Use Precompiled Header File ( /Yu ) компилятор игнорирует все директивы препроцессора (включая pragmas), которые отображаются в исходном коде, который будет предварительно скомпилирован. Компиляция, указанная такими директивами препроцессора, должна совпадать с компиляцией, используемой для параметра Create Precompiled Header File () (Файл заголовка). /Yc
Согласованность pragma
Pragmas, обрабатываемый во время создания PCH-файла, обычно влияет на файл, с которым позже используется PCH-файл. message И comment pragmas не влияют на оставшуюся часть компиляции.
Эти прагмы влияют только на код в PCH-файле; Они не влияют на код, который позже использует PCH-файл:
Эти прагмы сохраняются как часть предкомпилированного заголовка и влияют на оставшуюся часть компиляции, использующую предкомпилированный заголовок:
alloc_text
auto_inline
check_stack
code_seg
data_seg
function
include_alias
init_seg
inline_depth
inline_recursion
intrinsic
optimize
pack
pointers_to_members
setlocale
vtordisp
warning
Правила согласованности для /Yc и /Yu
При использовании предварительно скомпилированного заголовка, созданного с помощью /Yc или /Yu , компилятор сравнивает текущую среду компиляции с той, которая существовала при создании PCH-файла. Не забудьте указать среду, соответствующую предыдущей (с помощью параметров компилятора, прагм и т. д.) для текущей компиляции. Если компилятор обнаруживает несогласованность, он выдает предупреждение и по возможности определяет несогласованность. Такие предупреждения не обязательно указывают на проблему с файлом PCH. Они просто предупреждают о возможных конфликтах. В следующих разделах объясняются требования к согласованности для предкомпилированных заголовков.
Согласованность параметров компилятора
В таблице ниже перечислены параметры компилятора, которые могут вызвать предупреждение о несогласованности при использовании предкомпилированного заголовка.
| Параметр | name | Правило |
|---|---|---|
| /D | Определение констант и макросов | Должны быть одинаковыми в компиляции, создавшей предкомпилированный заголовок, и в текущей компиляции. Состояние определенных констант не проверяется. Однако непредсказуемые результаты могут возникнуть, если файлы зависят от значений измененных констант. |
| /E либо /EP | Копирование выходных данных препроцессора в стандартный вывод | Предварительно скомпилированные заголовки не работают с параметром или /EP параметром /E . |
| /Fr либо /FR | Создание сведений о браузере исходного кода Майкрософт | Чтобы параметры /Fr /FR были допустимыми с параметром /Yu , они также должны быть введены в действие при создании предварительно скомпилированного заголовка. При последующих компиляциях, использующих предкомпилированный заголовок, также создаются сведения о браузере исходного кода. Сведения о браузере помещаются в один .sbr файл и ссылаются на другие файлы так же, как и сведения CodeView. Невозможно переопределить размещение сведений о исходном браузере. |
| /GA , /GD , /GE , /Gw или /GW | Параметры протокола Windows | Должны быть одинаковыми в компиляции, создавшей предкомпилированный заголовок, и в текущей компиляции. Если эти параметры различаются, выдается предупреждение. |
| /Zi | Создание полной отладочной информации | Если при создании предкомпилированного заголовка этот параметр включен, последующие компиляции, использующие предварительную компиляцию, могут использовать отладочную информацию. Если /Zi не действует при создании предварительно скомпилированного заголовка, последующие компиляции, использующие предварительную компиляцию, и /Zi параметр активирует предупреждение. Сведения об отладке помещаются в текущий файл объекта, а локальные символы, определенные в предварительно скомпилированных заголовках, недоступны отладчику. |
Средство предварительно откомпилированных заголовков предназначено для использования только в исходных файлах C и C++.
Использование предварительно скомпилированных заголовков в проекте
В предыдущих разделах представлен обзор предкомпилированных заголовков: /Yc и /Yu, параметра /FP и прагмы hdrstop. В этом разделе описывается метод использования в проекте параметров заголовков, предкомпилированных вручную. В конце раздела приводится пример файла makefile и кода, который управляет им.
Для другого подхода к использованию параметров предварительно скомпилированного заголовка вручную в проекте изучите один из файлов makefile, расположенных в MFC\SRC каталоге, созданном во время настройки по умолчанию Visual Studio. Эти файлы makefile имеют аналогичный подход, представленный в этом разделе. Они делают больший доступ к макросам программы технического обслуживания (NMAKE) и обеспечивают более широкий контроль над процессом сборки.
PCH-файлы в процессе сборки
База кода проекта программного обеспечения часто содержится в нескольких исходных файлах C или C++, файлах объектов, библиотеках и файлах заголовков. Как правило, файл makefile координирует объединение этих элементов в исполняемый файл. На следующем рисунке показана структура файла makefile, использующего файл предкомпилированного заголовка. Имена макросов NMAKE и имена файлов на этой схеме согласуются с именами в примере кода, приведенного в примере файла makefile для PCH и примера кода для PCH.
На рисунке для отображения последовательности процесса сборки используются три схематических элемента. Прямоугольники представляют каждый файл или макрос; три макроса представляют один или несколько файлов. Затененные области представляют каждое действие компиляции или компоновки. Стрелки показывают, какие файлы и макросы объединяются во время процесса компиляции или компоновки.
Структура файла makefile, использующего файл предкомпилированного заголовка
Начиная с верхней части схемы и BOUNDRY являются макросами NMAKE, STABLEHDRS в которых список файлов, скорее всего, не требует перекомпиляции. Эти файлы компилируются с помощью командной строки
CL /c /W3 /Yc$(BOUNDRY) applib.cpp myapp.cpp
только в том случае, если файл предкомпилированного заголовка ( STABLE.pch ) не существует или если вы вносите изменения в файлы, перечисленные в двух макросах. В любом случае файл предкомпилированного заголовка будет содержать код только из файлов, перечисленных в STABLEHDRS макросе. Вывод списка последнего файла, предварительно скомпилированного в BOUNDRY макросе.
Файлы, перечисленные в этих макросах, могут быть файлами заголовков или файлами исходного кода C или C++. (Один PCH-файл нельзя использовать с источниками C и C++.) Макрос можно использовать для остановки hdrstop предварительной компиляции в какой-то момент в BOUNDRY файле. Дополнительные сведения см. в разделе hdrstop .
Далее на схеме представлен код поддержки, APPLIB.obj используемый в окончательном приложении. Он создается из APPLIB.cpp файлов, перечисленных в UNSTABLEHDRS макросе, и предварительно скомпилированного кода из предкомпилированного заголовка.
MYAPP.obj представляет конечное приложение. Он создается из MYAPP.cpp файлов, перечисленных в UNSTABLEHDRS макросе, и предварительно скомпилированного кода из предкомпилированного заголовка.
Наконец, исполняемый файл ( MYAPP.EXE ) создается путем связывания файлов, перечисленных в OBJS макросе ( APPLIB.obj и MYAPP.obj ).
Пример файла makefile для PCH
В следующем файле makefile используются макросы и !IF структура команд управления , !ELSE !ENDIF которая упрощает адаптацию проекта.
STABLEHDRS Помимо макросов, UNSTABLEHDRS показанных на рисунке «Структура файла Makefile, использующего файл предкомпилированного заголовка» в PCH-файлах в процессе сборки, этот файл makefile предоставляет CLFLAGS макрос и LINKFLAGS макрос BOUNDRY . Эти макросы необходимо использовать для перечисления параметров компилятора и компоновщика, которые применяются при сборке отладочной или финальной версии исполняемого файла приложения. Существует также LIBS макрос, в котором перечислены библиотеки, необходимые для проекта.
Файл makefile также использует !IF , !ELSE !ENDIF чтобы определить, определен ли символ в командной DEBUG строке NMAKE:
Эта функция позволяет использовать один и тот же файл makefile во время разработки и для окончательных версий программы. Используется DEBUG=0 для окончательных версий. Следующие строки команды являются эквивалентными.
Пример кода для PCH
Следующие исходные файлы используются в файле makefile, описанном в PCH-файлах в процессе сборки и образце файла makefile для PCH. Комментарии содержат важную информацию.