Амангельдинов О.С, Астапенко Н.В.
Северо-Казахстанский
Государственный Университет им.М.Козыбаева, Республика Казахстан
Precompiled Headers в
объектно-ориентированном программировании
В
незнакомой среде программирования всё кажется странным и непонятным. Очень часто
всё заканчивается тем, что новичок долгое время везде старательно отключает
Precompiled Headers. Язык программирования С++ для подключения внешнего модуля
использовал заголовочные файлы. Это упрощает компилятор и даёт некоторую
гибкость – и это работало в течение 20 лет, пока заголовки были небольшими, а
файлов в проекте – мало. С укрупнением программных проектов время компиляции
стало расти квадратично – увеличивается как количество единиц компиляции, так и
количество заголовков, подключённых к каждой конкретной единице. В особо
крупных проектах полная перекомпиляция занимает десятки минут и чаще
выполняется во время ночной сборки, чем на рабочих местах программистов.
Пред компилированные заголовки сохраняются на диске в виде
файлов во внутреннем формате компилятора и при повторных компиляциях проекта
время на их обработку и подключение существенно сокращается. Обычно программисты начинают знакомиться
с Visual C++, используя крошечные проекты. На них сложно заметить выигрыш от
precompiled headers. Что с ними, что без них, на глаз программа компилируется
одинаковое время. Это добавляет путаницы. Человек не видит для себя пользы от
этого механизма и решает, что он для специфичных задач и ему никогда не
понадобится. И иногда_считает_так_многие_годы.
На самом деле, precompiled headers весьма
полезная технология. Пользу от него можно заметить, даже если в проекте всего
несколько десятков файлов. Особенно выигрыш становится, заметен, если используются
такие тяжёлые библиотеки_как_boost.
Если
посмотреть *.cpp файлы в проекте, то можно заметить, что во многие включаются
одни и те-же наборы заголовочных файлы. Например, <vector>,
<string>, <algorithm>. В свою очередь, эти файлы включают другие
заголовочные_файлы_и_так_далее.
Всё
это приводит к тому, что препроцессор в компиляторе вновь и вновь выполняет
идентичную работу. Он должен читать одни и те же файлы, вставлять их друг в
друга, выбирать #ifdef ветки и подставлять значения макросов. Происходит
колоссальное дублирование одних и тех же операций.
Можно существенно сократить объем работы,
которую должен проделать препроцессор при компиляции проекта. Идея в том, чтобы
заранее препроцессировать группу
файлов и затем просто подставлять готовый фрагмент_текста.
На самом деле, делается ещё ряд шагов.
Можно хранить не просто текст, а более обработанную информацию. Я не знаю, как
именно устроено в Visual C++. Но, например, можно хранить текст уже разбитый на
лексемы. Это ещё больше ускорит процесс компиляции.
При
создании нового проекта Wizard в Visual Studio создаёт два файла: stdafx.h и
stdafx.cpp. Именно с помощью них и реализуется механизм precompiled headers.
На
самом деле, эти файлы могут называться, как угодно. Важно не название, а
параметры компиляции в настройках проекта.
В *.c/*.cpp файле можно использовать
только один precompiled header. Однако, в одном проекте может присутствовать
несколько разных precompiled headers. Пока будем считать, что он у нас только
один.
Итак, если вы воспользовались Wizard-ом, то
у вас уже есть файлы stdafx.h и stdafx.cpp. Плюс выставлены все необходимые
ключи компиляции.
Если в проекте не использовался механизм
precompiled headers, то возникает вопрос, как его включить. Некоторые авторы
предлагают следующую последовательность действий:
1.
Во всех
конфигурациях для всех *.c/*.cpp файлов включить использование precompiled
headers. Это делается на вкладке "Precompiled Header".
2.
Выставить
для параметра "Precompiled Header" значение "Use (/Yu)".
3.
Для параметра "Precompiled
Header File" указать
"stdafx.h".
4.
Для параметра "Precompiled
Header Output File" указать
"$(IntDir)$(TargetName).pch".
5.
Создать и
добавить в проект файл stdafx.h. В дальнейшем, в него будут включатся те
заголовочные файлы, которые хотим заранее препроцессировать.
6.
Создать и добавить
в проект файл stdafx.cpp. В нём одна единственная строка: #include
"stdafx.h"
7.
Во всех
конфигурациях менять настройки для файла stdafx.cpp. Выставить для параметра
"Precompiled Header" значение "Create (/Yc)".
Заголовочный
файл "stdafx.h" должен обязательно включаться в *.c/*.cpp файл самым
первым, иначе всё
равно возникнут ошибки компиляции.
Когда файл "stdafx.h" находится
в самом начале, то можно подставить уже препроцессированный текст. Этот текст
всегда одинаков и ни от чего не зависит.
Надеемся, что данные представленные в
статье будет интересны тем, кто желает познакомиться
со средой Visual Studio и пытается компилировать в ней свои С++ – проекты.
Список литературы
1. Понамарев Вячеслав Программирование
на C++ в Visual Studio
.NET 2003; Книга по Требованию - Москва, 2004. - 340 c
2.Пауэрс Ларс, Снелл Майк Microsoft Visual Studio 2008; БХВ-Петербург - Москва, 2009.
3.Майо Джо Microsoft Visual Studio 2010. Самоучитель; БХВ-Петербург - Москва, 2010. - 450
c.