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

Pragma hdrstop c что это

  • автор:

 

#pragma hdrstop

This directive terminates the list of header files eligible for precompilation. You can use it to reduce the amount of disk space used by precompiled headers.

Precompiled header files can be shared between the source files of your project only if the #include directives before #pragma hdrstop are identical. Therefore, you get the best compiler performance if you include common header files of your project before the #pragma hdrstop , and specific ones after it. Make sure the #include directives before the #pragma hdrstop are identical in all the source files, or that there are only very few variations.

The integrated development environment generates code to enhance precompiled header performance. For example, after a New Application, source file «Unit1.cpp» will look like this (comments added):

Use this pragma directive only in source files. The pragma has no effect when it is used in a header file.

Pragma hdrstop c что это

Прагмы hdrstop, no_implicit_inclusion, no_pch, once и system_header помогают компилятору обрабатывать заголовочные файлы проекта (*.h), используя предварительную компиляцию заголовков, что потенциально может уменьшить общее время компиляции проекта.

[#pragma hdrstop]

Прагма hdrstop pragma используется вместе с ключом командной строки -pch (precompiled header), см. врезку ниже. Опция -pch инструктирует компилятор искать файл предварительной компиляции заголовков (файл с расширением *.pch), и если не получилось его найти, то этот файл будет сгенерирован для использования в последующей компиляции. Файл *.pch содержит снимок всего кода, который был скомпилирован до точки останова предварительной компиляции (header stop point). Эта точка в исходном коде (или в заголовочном файле) задается директивой #pragma hdrstop.

-pch

Опция командной строки -pch (precompiled header) указывает компилятору автоматически генерировать и использовать файлы так называемые файлы предварительной компиляции заголовков (precompiled header files). Результат этой предварительной компиляции сохраняется в файл с расширением *.pch и именем, взятым из основного имени исходного файла. По умолчанию все precompiled headers сохраняются в каталоге с именем PCHRepository.

Следует иметь в виду, что файлы precompiled header занимают дополнительное место на диске (каждый такой файл может занимать несколько мегабайт).

Примечание переводчика: опытным путем выяснил, что опция -pch иногда приводит к ошибке cc0219, которую исправить никак не удается:

Ошибка проявлялась на 64-битной системе Windows 7, однако на другом компьютере с Windows XP 32 бита все компилировалось нормально.

По умолчанию точка header stop point (если #pragma hdrstop не используется) — первая не обрабатываемая предварительной компиляцией строка в основном исходном коде. Директива #pragma hdrstop может использоваться установки header stop point в файле исходного кода.

В следующем примере точка останова по умолчанию для предварительной компиляции — начало декларации переменной i.

Такой вариант выбора точки останова предварительной компиляции может быть плохим выбором, потому что заголовочный файл frequently_changing_data.h может находится на стадии разработки и подвергаться частым модификациям. Это приведет к тому, что файл *.pch будет часто генерироваться заново, и выгода использования precompiled header теряется. Прагма hdrstop может использоваться для того, чтобы выбрать более подходящее место для точки header stop.

В следующем примере файл precompiled header не будет включать frequently_changing_data.h, потому что он подключается после #pragma hdrstop. Поэтому precompiled header не нужно будет создавать заново каждый раз, когда был изменен frequently_changing_data.h.

[#pragma no_implicit_inclusion]

С помощью опции -c++ (см. врезку ниже) для каждого файла заголовка (с расширением *.h или без расширения), компилятор пытается подключить соответствующий файл *.c или .cpp. Это называется «неявное подключение» (implicit inclusion).

-c++

Эта опция (режим C++) указывает компилятору, что исходные файлы написаны в соответствии со стандартом ANSI/ISO языка C++, с добавлением расширений языка от Analog Devices.

В режиме по умолчанию допускаются все стандартные возможности C++, кроме обработки исключений (exception handling) и идентификаторов типа времени выполнения (run-time type identification), потому что это приводит к слишком большим расходам ресурсов и обычно неприемлемо для встраиваемых приложений. Поддержка этих функций может быть разрешена с помощью опций командной строки -eh и -rtti.

-eh

Опция -eh (разрешить exception handling) указывает компилятору, что в коде C++ разрешены операторы обработки исключений try/catch, и есть возможность выбрасывания исключений (throw exceptions) и другие функции, связанные с ANSI/ISO standard C++ exceptions. Когда этот ключ разрешен, компилятор определяет макрос __EXCEPTIONS как 1.

Если опция -eh используется при компиляции C-программ без опции -c++ (-c++ включает режим языка C++), то -eh указывает компилятору генерировать таблицы исключений, но не менять принятый язык. В этом случае макрос __EXCEPTIONS не определяется.

Опция –eh также заставляет компилятор определить __ADI_LIBEH__ во время стадии линковки, чтобы в ldf-файле [1] могли быть активированы соответствующие секции, и программа могла быть слинкована с библиотекой, собранной с разрешением обработки исключений (exceptions enabled library).

Объектные файлы, созданные с разрешением исключений, могут быть линкованы с объектными файлами, где обработка исключений не включена. Однако исключения могут выброшены и пойманы, и выполнен код очистки, в модулях, скомпилированных с -eh. Если сделана попытка выбрасывания исключения в функции, не скомпилированной с -eh, то будет вызвана функция abort или функция, зарегистрированная с помощью set_terminate. Подробнее см. раздел помощи «Exceptions Tables Pragma» VisualDSP.

Для не многопоточных приложений для передачи данных исключений используется буфер, не возвращаемый в кучу на выходе из приложения (метка exit приложения). Это позволяет избежать ненужного кода и не повлияет на поведение программы.

Опция -eh применяется, когда установлена галочка «C++ exceptions and RTTI» диалога свойств проекта VisualDSP++ (Compile -> Language Settings).

-no-eh

Опция -no-eh (запрет exception handling) указывает компилятору отменить разрешение обработки исключений языка C++ (ANSI/ISO C++ exception handling). Это режим по умолчанию для компилятора.

-rtti

Опция -rtti (разрешение идентификации типов во время выполнения кода, run-time type identification) указывает компилятору разрешить в программе использование выражений dynamic_cast и других функций ANSI/ISO C++ run-time type identification. Этот ключ также заставляет компилятор определить макрос __RTTI как 1.

Опция -rtti применяется, когда установлена галочка «C++ exceptions and RTTI» диалога свойств проекта VisualDSP++ (Compile -> Language Settings).

-no-rtti

Опция -no-rtti (запрет run-time type identification) указывает компилятору отменить разрешение поддержки dynamic_cast и других функций ANSI/ISO C++ run-time type identification. Это режим по умолчанию для компилятора.

Если строка #pragma no_implicit_inclusion помещена в заголовочный файл *.h (или файл без расширения), то компилятор не будет неявно подключать соответствующий файл *.c или .cpp при компиляции с опцией -c++. Это поведение влияет только на файл *.h (или файл без расширения), в котором есть строка #pragma no_implicit_inclusion, и соответствующие файлы *.c или *.cpp.

Например, если есть файл t.c, содержащий

и файлы m.h и m.c оба пустые, то командная строка:

покажет следующие зависимости для t.c:

Если следующая строка добавлена в m.h:

то запуск компилятора с той же командой ( ccblkfn -c++ t.c -M ) не покажет m.c в списке зависимостей:

[#pragma no_pch]

Прагма no_pch отменяет ключ -pch (precompiled headers) для определенного файла исходного кода. Она указывает компилятору, что он не должен искать файл *.pch, и не должен генерировать его для указанного файла исходного кода.

[#pragma once]

Прагма once предназначена для замены набора директив #ifndef/#define/#endif. Это просто «синтаксический сахар», используемый для красоты и удобства.

Директива #pragma once должна находиться в начале заголовочного файла. Она говорит компилятору, что этот заголовочный файл написан таким образом, что его однократное подключение дает тот же эффект, как и многократное подключение. Т. е., говоря по-русски, заголовочный файл с #pragma once должен подключаться в проекте только один раз, даже если директива #include этого файла встречается во многих модулях проекта. Например,

Примечание: в этом примере директиву #pragma once в действительности указывать необязательно, потому что компилятор увидит директивы #ifndef, #define и #endif, и не будет повторно обрабатывать этот заголовок.

[#pragma system_header]

Прагма system_header pragma идентифицирует файл как файл, предоставленный системой программирования VisualDSP++. Компилятор VisualDSP++ использует эту информацию, чтобы помочь оптимизации использования предоставляемых библиотечных функций и inline-функций, которые определены этими файлами. Не используйте эту прагму в исходном коде пользовательского приложения.

What does #pragma hdrstop without parameter do when used in multiple files?

What is the practical value («what does it do») of putting #pragma hdrstop (no filename parameter) in a couple of source (cpp) files?

Note that the MSDN docs are (once again) as clear as mud to me.

Edit/Note: I’m asking this, because this answer and the article it links to seem to recommend that. But I do not understand what benefit it has to have a separate pch file for each compilation unit.

3 Answers 3

The answer to the original question is that the purpose of having #pragma hdrstop in a file with neither /Yc or /Yu set is that it’s ignored and so you can set up a build configuration which builds without precompiled headers and other build configurations that build WITH precompiled headers and you don’t need to change the code or the headers that are included at all to do so.

The notes on MSDN say that «The hdrstop pragma gives you additional control over precompilation file names and over the location at which the compilation state is saved.» which is true, but it’s not especially obvious exactly how useful that can be.

  • Putting #pragma hdrstop in a source file that isn’t compiled with /Yc or /Yu has no effect at all.
  • If you have /Yu set for the file then hdrstop tells the compiler to throw away everything before the line on which hdrstop appears and insert the precompiled header instead.
  • If /Yc is set for the file then hdrstop means save all of the compiled state for everything up to the line on which hdrstop appears as the precompiled header.

The trick is using /Yc and /Yu without the optional header file name; just check the ‘use’ or ‘create’ radio button and leave the ‘through header’ edit box blank (or edit the project file. ).

So you have 1 file, possibly called PrecompiledHeader.cpp which includes the headers that you want to include in the precompiled header and which has #pragma hdrstop at the end of the list of include files. This ONE file is compiled with /Yc.

You then have all your other cpp files with #pragma hdrstop after the include files that are in your precompiled header. These files are all compiled with /Yu.

This results in PrecompiledHeader.cpp building your (in this example) single pch file and all of the other files using that single pch file.

The advantage in doing this is that NONE of your files need to include a ‘global’ precompiled header building header file — so no stdafx.h or whatever. This means that you can set up a build configuration which builds WITHOUT precompiled headers where all of the #pragma hdrstop lines are simply ignored.

This is «good» because it means that you can have a single ‘no precomp’ build configuration which lets you develop quickly (you can change a single header and NOT force the world to rebuild) and other «normal» configurations that DO use precompiled headers.

5.3.6 Операторы перехода

Операторы перехода выполняют безусловную передачу управления.

break – оператор прерывания цикла.

if (<выражение_условие>) break;

 

Т. е. оператор break целесообразно использовать, когда условие продолжения итераций надо проверять в середине цикла.

// Найти сумму чисел, числа вводятся с клавиатуры до тех пор, пока не будет //введено 100 чисел или 0.

if( x==0) break; // если ввели 0, то суммирование заканчивается

continue – переход к следующей итерации цикла. Он используется, когда тело цикла содержит ветвления.

//Найти количество и сумму положительных чисел

goto <метка> – передает управление оператору, который содержит метку.

В теле той же функции должна присутствовать конструкция: <метка>:оператор;

Метка – это обычный идентификатор, областью видимости которого является функция. Оператор goto передает управления оператору, стоящему после метки. Использование оператора goto оправдано, если необходимо выполнить переход из нескольких вложенных циклов или переключателей вниз по тексту программы или перейти в одно место функции после выполнения различных действий.

Применение goto нарушает принципы структурного и модульного программирования, по которым все блоки, из которых состоит программа, должны иметь только один вход и только один выход.

Нельзя передавать управление внутрь операторов if, switch и циклов. Нельзя переходить внутрь блоков, содержащих инициализацию, на операторы, которые стоят после инициализации.

return – оператор возврата из функции. Он всегда завершает выполнение функции и передает управление в точку ее вызова. Вид оператора:

5.4 Пример простейшего проекта

Вычислить периметр, площадь и диагональ прямоугольника со сторонами a и b. После // в программе написан комментарий к строкам.

Форма для данного проекта может быть, например такой, как на рис.

Рисунок 6 — Форма проекта

#pragma hdrstop #include «Unit1.h»

#pragma resource «*.dfm»

#include <math.h> // подключение математической библиотеки

_fastcall TForm 1::TForm 1 (TComponent* Owner) : TForm(Owner)

// сюда помещаются операторы,

// которые должны выполняться при создании формы

Label5->Visible=0; // и Label5

void_fastcall TForm1::Button2Click(TObject *Sender)

// сюда помещаются операторы,

// которые должны выполняться при нажатии на Button2 , обязательно необходимо нажать мышкой на форме на кнопку Button2 два раза

Close(); // закрывает форму

void fastcall TForm1::Button1Click(TObject *Sender)

// сюда помещаются операторы,

// которые должны выполняться при нажатии на Button1, обязательно необходимо нажать мышкой на форме на кнопку Button1 два раза

double a, b; // объявление переменных

a= StrToFloat(Edit 1->Text); // введенное значение в поле Edit 1 запомнится // в переменной а

double S, P, D; // объявление переменных

P=2*(a+b); // вычисление выражения

Label4->Visible=1; // сделать видимыми метку Label4

Label4->Caption=» Периметр прямоугольника Р left»> Label5->Caption=» Площадь прямоугольника S left»> Label6->Caption=»Диагональ прямоугольника D left»> >

В конструктор форм внесены операторы, делающие невидимыми метки Label4 и Label5 в момент создания формы. Эти метки используются в обработчике кнопки для вывода результатов на экран. Основные вычисления производятся в подпрограмме ButtonlClick. Обратите внимание, что после заголовка подпрограммы следует открывающая фигурная скобка. Фигурные скобки ( <> ) в С всегда используются парами (открывающая и закрывающая) и являются операторными скобками.

объявляет вещественные переменные R и L. Все переменные в языке С должны быть объявлены перед их использованием.

R=StrToFloat(Edit 1 ->Text); является оператором присваивания. Переменной R присваивается содержимое редактора Editl. Для перевода значения из строки в вещественное число ис­пользуются, как и в Delphi, функция StrToFloat. Для обращения к свойству компонента используется символы «-» и «>», записанные без пробела.

При написании программы помните, что большие и маленькие буквы в языке C++ различаются, в отличие от Delphi. То есть, например, переменные R и r считаются различными.

Пример 2: Сформировать последовательность из n целых чисел. Определить минимальный элемент и количество четных чисел.

Рисунок 7 — Форма проекта

#pragma resource «*.dfm»

__fastcall TForm1::TForm1(TComponent* Owner)

void __fastcall TForm1::Button1Click(TObject *Sender)

i=i+1; // Увеличивает значение переменной i на единицу

if ((x%2)==0) k++; // Если остаток от деления х на 2 равен 0, то значение

// переменной к увеличивается на 1

void __fastcall TForm1::Button2Click(TObject *Sender)

Пример 3: S=4+7-10+13+16-19+22+25-28+…, всего n слагаемых;

#pragma resource «*.dfm»

__fastcall TForm1::TForm1(TComponent* Owner)

void __fastcall TForm1::Button1Click(TObject *Sender)

do // начало цикла

if (k%3= =0) s=s-i; else s=s+i; // Если остаток от деления переменной к

// на 3 равен нулю, то от переменной s отнимаем i, иначе к переменной s

// прибавляем i

while (k<n); // конец цикла. Цикл выполняется до тех пор, пока k<n

Label2->Caption=» S left»> >

Для справки

Директива #pragma имеет следующий синтаксис: #pragma имя опции и вызывает действия, зависящие от указанной опции. Список возможных опций вы можете найти во встроенной справке C++Builder. Он довольно обширен и связан с различными режимами работы препроцессора. Пример директивы #pragma вы можете видеть в любом модуле своего проекта. Первые две строки файла любого модуля имеют вид: #include <vcl.h> #pragma hdrstop Здесь использована опция hdrstop. Она связана с особенностью работы препроцессора, производительность которого существенно повышается, если учитывается, что некоторое количество заголовочных файлов общие для всех модулей. Директива #pragma hdrstop указывает компилятору конец списка таких общих файлов. Так что надо следить за тем, чтобы не добавлять перед этой директивой включение каких-то заголовочных файлов, не являющихся общими для других модулей. В файлах модулей вы можете еще увидеть две директивы #pragma: #pragma package(smart_init) #pragma resource «*.dfm» Первая из них определяет последовательность инициализации пакетов такой, какая устанавливается взаимными ссылками использующих их модулей. Вторая говорит препроцессору, что для формы надо использовать файл .dfm с тем же именем, что и имя данного файла. . Например, директива #include <vcl.h> подключает заголовочный файл vcl.h, содержащий объявления, используемые в библиотеке визуальных компонентов C++Builder. . Следующая директива включает файл Unit1.h, который ищется прежде всего в каталоге, в котором расположен файл, содержащий данную директиву: #include «Unit1.h»

TForm1 *Form1;

Так объявляется указатель с именем Form1 на объект класса TForm1, в дальнейшем он может использоваться для доступа к свойствам и методам формы с именем «Form1».

void __fastcall TForm1::Edit1Click(TObject *Sender)

Так начинается определение обработчика события OnClick для компонента типа TEdit с именем «Edit1», принадлежащего форме с именем «Form1».

 

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

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