Амангельдинов О.С, Астапенко Н.В.

Северо-Казахстанский Государственный Университет им.М.Козыбаева, Республика Казахстан

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.