Принцип дії предкомпілірованних заголовків

Для управління предкомпілірованнимі призначена директива компілятора
# Pragma hdrstop. Всі заголовні файли, включені до цієї директиви,
містяться в один образ, наприклад:

#include <vcl.h>
#include <string>
#pragma hdrstop

Така послідовність створить образ, що містить скомпільовані vcl.h і
string. Цей образ буде використаний для іншого cpp-файлу, якщо в ньому до
директиви hdrstop будуть включені ті ж файли, в тому ж порядку. Зверну увагу,
що важливий не тільки склад, але й порядок проходження заголовків – навіть якщо
наступний cpp-файл включає ті ж заголовки, але спочатку вказано string, а потім
vcl.h, то для цього cpp-файлу буде створений новий образ.

Таким чином, для повторного використання предкомпілірованного заголовка
необхідне виконання двох умов:


Скоротити витрати на компіляцію стандартних заголовків до мінімуму можна
тільки в тому випадку, якщо скомпілювати один образ, що містить всі стандартні
заголовки, необхідні для проекту. Для цього потрібно, щоб:


Виконати ці умови досить просто, для цього на початку кожного cpp-файлу
необхідно помістити наступні рядки:


#include <pch.h>
#pragma hdrstop

де pch.h – файл, що містить включення всіх стандартних заголовків:


#ifndef PCH_H
#define PCH_H

#define INC_VCLDB_HEADERS
#define INC_VCLEXT_HEADERS
#include <vcl.h>

#include <sysset.h>
#include <IniFiles.hpp>
#include <AppEvnts.hpp>
#include <ActnMan.hpp>

#endif


Повний текст моєї версії цього файлу наведений в кінці статті. На h-файли,
входять до предкомпілірованний образ, накладається обмеження – в них не
повинно бути ініціалізованих даних, наприклад, в math.hpp є рядки:


static const Extended NaN = 0.0 / 0.0;
static const Extended Infinity = 1.0 / 0.0;

Через наявність цих констант включити math.hpp в файл pch.h не можна.

До речі, С + + Builder при додаванні нових модулів в проект реалізує описану
стратегію управління предкомпілірованнимі заголовками. Наприклад, при створенні
нової програми, файл Unit1.cpp буде таким:


#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
….


Якщо подивитися на текст vcl.h, то можна побачити, що він є оболонкою
для включення великої кількості інших стандартних заголовків файлів.

Управляти складом включаються до vcl.h заголовків можна за допомогою спеціальних
символів (INC_VCLDB_HEADERS, INC_VCLEXT_HEADERS та ін.) У моїй версії pch.h ці
символи визначаються за допомогою # define до включення vcl.h, що призводить до
збільшення числа включення файл.

Як в існуючому проекті перейти до використання предкомпілірованних
заголовків

Навіть у великому проекті перейти до використання предкомпілірованних заголовків
досить просто.

У властивостях проекту потрібно включити кешування предкомпілірованних заголовків
і рекомендується вказати "персональний" файл, в якому буде зберігатися образ
предкомпілірованних заголовків: Project – Options – закладка Compiler, група
"Pre-compiled headers". Тут повинно бути вибрано "Cache pre-compiled headers", а
в полі "File Name" потрібно ввести "pch.csm". При такій настройці образ з
предкомпілірованнимі заголовками буде знаходиться в папці з проектом, у файлі
pch.csm.

Після цього на початку кожного cpp-модуля необхідно вставити 2 рядки:


#include "pch.h"
#pragma hdrstop

Всі раніше включених заголовні файли залишаються на своїх місцях, їх видаляти
не треба. Наприклад:


# Include "pch.h" / / включає vcl.h, string і т.д.
#pragma hdrstop

#include <vcl.h>
#include <string>


Так як у всіх стандартних заголовках застосовуються варти повторного
включення, то повторне їх згадка не тягне за собою повторного включення.

У принципі, при використанні pch.h, технічна потреба у включенні
стандартних заголовків зникає. Однак, корисно все ж вказувати всі
необхідні для кожного конкретного модуля заголовки нижче директиви # pragma
hdrstop. По-перше, це в деякій мірі документує модуль – по включаються
файлів можна судити, якими можливостями користується цей модуль. По-друге, це
полегшує повторне використання модуля в інших проектах, в яких або не
використовується pch.h, або його вміст може бути іншим.

Теоретично можна ще більше підвищити ефективність компіляції, якщо
включити до pch.h не тільки стандартні, але і всі призначені для користувача заголовні
файли. Практично, так як для користувача заголовки змінюються досить
часто, це може спричинити за собою часту перекомпіляцію pch.h, що негативно
позначиться на часі компіляції. Крім того, призначені для користувача заголовки зазвичай не
бувають дуже великими і компілюються дуже швидко. Тому включати їх pch.h НЕ
доцільно.

Як перевірити, що предкомпілірованние заголовки використовуються ефективно

При додаванні до проекту нових файлів потрібно не забувати включати в них pch.h,
інакше для них не буде використаний загальний предкомпілірованний образ. Така ж
ситуація може виникнути, якщо в якомусь модулі включаються стандартні
заголовки, які не увійшли до pch.h. Для того, щоб відстежити такі файли, є
кілька способів:


Текст pch.h


#ifndef PCH_H
#define PCH_H

#define INC_VCLDB_HEADERS
#define INC_VCLEXT_HEADERS
#include <vcl.h>
/ * Все, що підключається попередніми 3-ма рядками
// Core (minimal) Delphi RTL headers
#include <System.hpp>
#include <Types.hpp>
#include <Windows.hpp>
#include <Messages.hpp>
#include <SysUtils.hpp>
#include <Classes.hpp>

// Core (minimal) VCL headers
#if defined(INC_VCL)
#include <Controls.hpp>
#include <Graphics.hpp>
#include <Forms.hpp>
#include <Dialogs.hpp>
#include <StdCtrls.hpp>
#include <ExtCtrls.hpp>

// VCL Database related headers
#if defined(INC_VCLDB_HEADERS)
#include <DBCtrls.hpp>
#include <DB.hpp>
#include <DBTables.hpp>
#endif // INC_VCLDB_HEADERS

// Full set of VCL headers
#if defined(INC_VCLEXT_HEADERS)
#include <Buttons.hpp>
#include <ChartFX.hpp>
#include <ComCtrls.hpp>
#include <DBCGrids.hpp>
#include <DBGrids.hpp>
#include <DBLookup.hpp>
#include <DdeMan.hpp>
#include <FileCtrl.hpp>
#include <GraphSvr.hpp>
#include <Grids.hpp>
#include <MPlayer.hpp>
#include <Mask.hpp>
#include <Menus.hpp>
#include <OleCtnrs.hpp>
#include <OleCtrls.hpp>
#include <Outline.hpp>
#include <Tabnotbk.hpp>
#include <Tabs.hpp>
#include <VCFImprs.hpp>
#include <VCFrmla1.hpp>
#include <VCSpell3.hpp>
#endif // INC_VCLEXT_HEADERS

#endif // INC_VCL
*/

#include <sysset.h>
#include <IniFiles.hpp>
#include <AppEvnts.hpp>
#include <ActnMan.hpp>
#include <ActnCtrls.hpp>
#include <BandActn.hpp>
#include <CustomizeDlg.hpp>
#include <ImgList.hpp>
#include <ToolWin.hpp>
#include <ExtDlgs.hpp>
#include <ActnList.hpp>

#include <IBDatabase.hpp>
#include <IBCustomDataSet.hpp>
#include <IBQuery.hpp>
#include <IBTable.hpp>
#include <IBSQL.hpp>
#include <IBServices.hpp>

#include <math.h>
#include <assert.h>
#include <complex.h>
#include <values.h>

#include <map>
#include <list>
#include <set>
#include <vector>
#include <algorithm>
#include <functional>
#include <string>
#include <memory>
#include <fstream>

/ / Нестандартні компоненти RxLib і EhLib
#include "CURREDIT.hpp"
#include "RXSpin.hpp"
#include "RxCalc.hpp"
#include "RxCombos.hpp"
#include "APPUTILS.hpp"
#include "RXDBCtrl.hpp"
#include "Placemnt.hpp"
#include "DBGridEh.hpp"

#endif

Схожі статті:


Сподобалася стаття? Ви можете залишити відгук або підписатися на RSS , щоб автоматично отримувати інформацію про нові статтях.

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*