Pragma hdrstop c что это
Перейти к содержимому

Pragma hdrstop c что это

Иллюстрированный самоучитель по C++ Builder

Начинается консольное приложение директивой #pragma hdrstop, которая запрещает выполнение предварительной компиляции подключаемых файлов. После этой директивы надо вставить директивы #inciude, обеспечивающие подключение необходимых библиотек (например, #include <stdio.h>). Директива #pragma argsused отключает предупреждение компилятора о том, что аргументы, указанные в заголовке функции, не используются.

Следует обратить внимание на то, что консольное приложение разрабатывается в Windows, а выполняется как программа DOS. В DOS и Windows буквы русского алфавита имеют разные коды (в DOS используется кодировка ASCII, а в Windows – ANSI). Это приводит к тому, что консольное приложение вместо сообщений на русском языке выводит "абракадабру".

Проблему вывода сообщений на русском языке консольными приложениями можно решить, разработав функцию перекодировки ANSI-строки в строку ASCII. Если эту функцию назвать rus, то инструкция вывода сообщения может выглядеть, например, так:

В качестве примера консольного приложения в листинге 7.1 приведена программа "Угадай число", которая для вывода сообщений использует функцию RUS. Значение функции rus – строка символов в кодировке ASCII, соответствующая строке, полученной в качестве параметра.

С++ Builder: как ускорить компиляцию с помощью предкомпилированных заголовков

Вместо вступления сразу приведу пример. Полная сборка (build) проекта, содержащего около 170 cpp-модулей, при использовании предкомпилированных заголовков происходит за 811 секунд, при этом число обработанных компилятором строк составляет 1,808,780. При компиляции того же проекта без использования предкомпилированных заголовков, время сборки составляет 2399 секунд, а число строк, обработанных компилятором — 45,261,820. Впечатляет, не так ли? Плата за это ускорение, в принципе не велика — предкомпилированный образ, размер которого около 40 Мб.

При компиляции исходных текстов, компилятор должен обработать все *.cpp файлы проекта и все включенные в них *.h — файлы. При этом обрабатываются как пользовательские заголовочные файлы, так и стандартные, такие как vcl.h или Word2k.h. Количество кода, находящегося в стандартных заголовках может быть очень большим, например размер файла Word2k.h превышает 5 Мб, в нем больше 130 000 строк кода.

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

Принцип действия предкомпилированных заголовков

Для управления предкомпилированными предназначена директива компилятора #pragma hdrstop. Все заголовочные файлы, включенные до этой директивы, помещаются в один образ, например:

Такая последовательность создаст образ, содержащий скомпилированные vcl.h и string. Этот образ будет использован для другого cpp-файла, если в нем до директивы hdrstop будут включены те же файлы, в том же порядке. Обращу внимание, что важен не только состав, но и порядок следования заголовков — даже если следующий cpp-файл включает те же заголовки, но сначала указан string, а потом vcl.h, то для этого cpp-файла будет создан новый образ.

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

  • состав включенный файлов до директивы hdrstop должен быть тем же
  • последовательность включения файлов до директивы hdrstop должна быть той же

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

  • ВСЕ cpp-файлы проекта имели одинаковый блок включений до директивы hdrstop
  • в этот блок должны входить ВСЕ стандартные заголовочные файлы, необходимые для проекта

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

где pch.h — файл, содержащий включения всех стандартных заголовков:

Полный текст моей версии этого файла приведен в конце статьи. На h-файлы, входящие в предкомпилированный образ, накладывается ограничение — в них не должно быть инициализированных данных, например, в math.hpp есть строки:

Из-за наличия этих констант включить math.hpp в файл pch.h нельзя.

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

Если посмотреть на текст 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 строки:

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

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

Что делает #pragma hdrstop

If a C or C++ file contains a hdrstop pragma when compiled with either /YX or /Yc, the compiler saves the state of the compilation up to the location of the pragma. The compiled state of any code that follows the pragma is not saved.

Всё равно неясно для чего это нужно и нужно ли вообще.

Собственно тоже сталкнулся с этим, Быдлер постоянно сует ее в чистых проектах, что делает сия директива? Я ее просто удаляю, но может она зачем-то нужна?

Типа PCH, тока не понятно, для чего так, если есть нормальные средства для этого.

MAMONT-92 [REBORN]
А ты загугли.

Ну на мсдне вроде все понятно написано, сохраняет все состояние компиляции до этой прагмы, если файл откомпилированного заголовка указан то он вступает в силу с только после этой прагмы, если не указан то берется дефолтный, опять же таки только после этой прагмы

кароче можно просто удалять и не волнует, так?

Wraith
> А ты загугли.
а я через гуголь и попал сюда.

MAMONT-92 [REBORN]
> кароче можно просто удалять и не волнует, так?
если стоит вначале, и выше только #include ". /precompiled.h" — Да

#pragma hdrstop — своеобразный аналог PCH — все заинклуденные хидеры до #pragma hdrstop будут прекомпилированы и закешены, если где еще в C/CPP файлах компилятор встретит ту же последовательность хидеров до #pragma hdrstop — то заюзается уже скомпиленый кеш.

А в небыдлер-м$ $тудии с этой же целью заставляют инклудить stdafx.h, причём принудительно. Так-то!

Sbtrn. Devil
это был один из агрументов, почему ушел со студии, там без этой хрени ничего не компилилось.

MAMONT-92 [REBORN]
> это был один из агрументов, почему ушел со студии, там без этой хрени ничего не
> компилилось.
Бедняжка. Хоть не на линукс перешел?

Если тебя бесит то, что проект собирается быстрее, то можно отключить "юзинг прекомпаилед хиадерc" в настройках.

entryway
> Бедняжка. Хоть не на линукс перешел?
Линукс — это поделка собранная на коленке в туалете полная всевозможных костылей.

MAMONT-92 [REBORN]
> Sbtrn. Devil
> > А в небыдлер-м$ $тудии с этой же целью заставляют инклудить stdafx.h, причём принудительно. Так-то!
> это был один из агрументов, почему ушел со студии, там без этой хрени ничего не компилилось.
пф-пф-пф.

Sbtrn. Devil
> А в небыдлер-м$ $тудии с этой же целью заставляют инклудить stdafx.h, причём принудительно. Так-то!

Ну что за бред. Никто никого не заставляет, в чистом проекте вообще нет никаких stdafx.h. Я в каждом новом проекте сам создаю stdafx.h такой, какой мне нужен.
А если уж так хочется создать проект визардом и при этом убрать stdafx.h и при этом не хочется убирать галочку ответственную за это (нафига тока не ясно), то при желании парой кликов PCH отключается.

MAMONT-92 [REBORN]
> это был один из агрументов, почему ушел со студии, там без этой хрени ничего не компилилось.

Лол. Можно это просто не использовать.
Но так как эта вещь очень полезна, то не вижу смысла её не использовать.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *