Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

[C++] Używanie #pragma hdrstop

Ostatnio zmodyfikowano 2025-06-04 00:22
Autor Wiadomość
DejaVu
Temat założony przez niniejszego użytkownika
[C++] Używanie #pragma hdrstop
» 2013-02-20 12:30:46
Mamy sobie zapis:
C/C++
#pragma hdrstop

http://msdn.microsoft.com/en-us/library/263e9b36(v=vs.80).aspx

Jaka jest idea używania tego zapisu? Gdzieś przeczytałem, że ponoć przyśpiesza to proces kompilacji, ale nie doczytałem w którym miejscu w kodzie warto wstawiać ten zapis, aby uzyskać prawidłowy efekt tj. rzeczywiste przyśpieszenie procesu kompilacji.

Druga sprawa to czy da się wstawić wspomnianą linijkę w złym miejscu co np. spowoduje efekt odwrotny do zamierzonego.

Trzecia sprawa to czy mogą wystąpić jakiekolwiek efekty uboczne w przypadku wstawienia tej linijki w złym miejscu (np. błędy kompilacji/nieprawidłowe linkowanie itp).
P-76569
usmiech
» 2013-02-20 13:58:12
Z tego co wiem jest to nowosc C++, wiec nie wszystkie kompilery ja 'realizuja' /te 'ktore jej nie znaja, pomijaja ja/.#pragma to dyrektywa dla preprocesora , czyli umieszczana jest w head.

#pragma once

Jest to jakby straznik chroniacy programiste przed wielokrotnym uzywaniem teko samego pliku w roznych defninicjach umieszczanych w head.

For example, suppose A.h includes Logger.h and
B.h also includes Logger.h. If you have a source fi le called App.cpp which includes both A.h and B.h,
the compiler will not complain about a duplicate defi nition of the Logger class because the Logger.h
header will be included only once, even though A.h and B.h both include it.

#pragma [xyz]

xyz varies from compiler to
compiler. Often allows the programmer to display a warning or error if the directive is reached during preprocessing.

#pragma hdrstop

W C++ Builder ta pragma instruuje preprocesor, ze nie powinien generowac /albo raczej wspoldzielic / precompiled headers dla zadnych #included plikow bedacych poza ta dyrektywa. Wiec dyrektywa ta rzeczywiscie moze przyspieszyc kompilacje redukujac czas czytania i realizowania dyrektyw dla preprocesora. Szczegolnie jesli w head znajduje sie np b.duza dyrektywa jak <windows.h>. Mysle, ze dyrektywa ta zjajduje zastosowanie jesli nasz program jest wieloplikowy i w kazdym z nich mamy head,  zawierajacy te same dyrektywy dla preprocesora /C++ przetworzy wszystkie dyrektywy head w tych plkach tylko raz dzieki umieszczeniu dyrektywy #pragma hdrstop w odpowiednim miejscu head/. Jak widac od nas zalezy w ktorym miejscu head wstawimy ta dyrektywe.../najlepiej przed ta dyrektywa umiescic najwieksze dyrektywy, wspolne dla wszystkich plikow , a za nia dyrektywy specyficzne dla danego pliku, wtedy najlepiej osiagniemy nasz cel uzywania pragma.Pamietac musimy, aby we wszyskich plikach byly takie same dyrektywy przed pragma /.

Chyba troche namieszalem ze slownictwem, sorki, ale ucze sie w jezyku angielskim i tlumaczenie nieraz to klopot. Mam nadzieje, ze pomimo wszystko tekst jest zrozumialy hahhaha :)

The C++ specification allows for a certain type of compiler-defined language extension through
the #pragma mechanism. #pragma is a precompiler directive whose behavior is defined by the
implementation. If the implementation does not understand the directive, it ignores it. For example,
some compilers allow the programmer to turn compiler warnings off temporarily with #pragma.

Sorki za angielski. Pozdrawiam :)

A nawiasem mowiac, najwiekszy program, o ktorym slyszalem, kompiluje sie ok 24 godzin... czyli kazde przyspieszenie pracy moze byc istotne :)

Precompiled header files can be shared between the various source files of your project only if the header files listed prior to the #pragma hdrstop are identical.  In other words, it is important to make sure the #include directives before the #pragma hdrstop are identical in all the source files, or that there are only very few variations.

In this way, you get the best compiler performance if you include common header files (e.g. #include <vcl.h>) before the #pragma hdrstop directive, while specific header files (e.g. #include "Unit1.h") should be included after it.

For example, the following code is generated when a New Application is generated: (comments added)

C/C++
//---------------------------------------------------------------------------
#include <vcl.h>    // Common header file
#pragma hdrstop

#include "Unit1.h"  // Specific header file
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 * Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1( TComponent * Owner )
    : TForm( Owner ) // #include <windows.h> #include <vcl.h> #include ... whatever else you need ...#pragma hdrstop #pragma once // ... the contents of this header file #pragma once #include “Preferences.h” class Logger
{
public:
    static void setPreferences( const Preferences & inPrefs );
    static void logError( const char * inError );
};
P-76572
DejaVu
Temat założony przez niniejszego użytkownika
» 2013-02-20 17:48:26
To nie jest żadna nowość, skoro dostępne jest w kompilatorze dostarczonym z Visual C++ 2005 oraz Borland C++ Builder z roku bodajże 2003. Nie chodzi mi o tłumaczenie zdań z angielskiego na polski, tylko o wiedzę wynikającą z praktycznego własnego doświadczenia :)
P-76579
usmiech
» 2013-02-21 05:39:39
Taki program napisze za jakies 3 miesiace hahhhahahahahaha, to powiem ;-)
P-76604
krzyk
» 2013-02-21 10:00:36
Ta dyrektywa niczego niewymusza tylko próbuje więc jeśli kompilator nie może użyć prekompilowanych nagłówków to ignoruje ją.
W zasadzie napisałem tylko jeden większy projekt(nadal go piszę) w borlandzie i z moich spostrzeżeń wynika że nieużywając
#pragma hdrstop
 kompiluje się(rebuild) o około 2-3% dłużej(około 3min) więc chyba działa.
Zauważyłem tez że lepiej dodać do *.cpp zbędne "include" tylko po to by kolejność dołączanych nagłówków była odpowiednia(w borlandzie kolejność nagłówków ma znaczenie).
Co do błędów kompilacji lub linkowania to niedoznałem żadnych nieprzyjemności,z tego co wiem nie ma sensu używać hdrstop z nagłówkami które często są modyfikowane a tylko w takim przypadku mogłyby wystąpić ewentualne błędy z linkowaniem.

/EDIT
Nie używałem szablonów ale podejrzewam że niwelują próbę optymalizacji,przynajmniej te różnie skonkretyzowane.
P-76606
termistor
» 2025-06-04 00:22:41
#pragma hdrstop to dyrektywa specyficzna dla kompilatora, która wskazuje, gdzie kończy się część nagłówkowa kodu, która ma być prekompilowana. Jej głównym celem jest przyspieszenie kompilacji, zwłaszcza w projektach wieloplikowych, gdzie wiele plików źródłowych może zawierać te same nagłówki.  

### Dlaczego działa?  
Przy użyciu
#pragma hdrstop
, kompilator:  
- Przetwarza wszystkie nagłówki przed tą dyrektywą jako precompiled header.  
- Ignoruje nagłówki po niej, co unika ponownego przetwarzania tych samych plików w każdym pliku źródłowym.  

### Gdzie wstawiać?  
Najlepszym miejscem jest pierwsza część nagłówków wspólnych dla całego projektu. Przykład:  
 
#include <windows.h>  
#include <vcl.h>  
#pragma hdrstop  
#include "Unit1.h"  
#include "Logger.h"  
 
Nagłówki przed
#pragma hdrstop
 powinny być identyczne we wszystkich plikach źródłowych. W przeciwnym razie kompilator nie będzie mógł skorzystać z prekompilacji.  

### Efekty uboczne i błędy  
- **Zła lokalizacja**: Jeśli dyrektywa jest wstawiona po nagłówkach specyficznych dla danego pliku, kompilator nie będzie mógł prekompilować tych nagłówków, co może spowolnić kompilację.  
- **Często modyfikowane nagłówki**: Jeśli nagłówki przed
#pragma hdrstop
 są często zmieniane, prekompilacja zostanie ponownie generowana, co może niwelować korzyści.  
- **Błędy linkowania**: Występują rzadko, ale mogą się pojawić, jeśli nagłówki po
#pragma hdrstop
 są niezgodne z definicjami w innych plikach.  

### Dobry praktyki  
- Umieszczaj
#pragma hdrstop
 przed nagłówkami wspólnymi (np.
<windows.h>
).  
- Po niej dołączaj nagłówki specyficzne dla danego pliku.  
- Unikaj jej użycia w nagłówkach, które często zmieniają się (np. w projekcie z intensywnym użyciem szablonów).  

### Praktyczny przykład  
W Borlandzie C++ Builder:  
 
#include <vcl.h>  
#pragma hdrstop  
#include "Unit1.h"  
#pragma package(smart_init)  
#pragma resource "*.dfm"  
TForm1 *Form1;  
__fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) {}  
 
Takie rozmieszczenie zapewnia, że
<vcl.h>
 jest prekompilowany, a
"Unit1.h"
 przetwarzany osobno.  

### Szablony i optymalizacja  
Szablony (np.
std::vector<int>
) są rozszerzane w czasie kompilacji. Jeśli są umieszczone po
#pragma hdrstop
, nie skorzystają z prekompilacji. Dlatego warto je dołączać przed tą dyrektywą, jeśli są wspólnymi elementami projektu.  

### Podsumowanie  
-
#pragma hdrstop
 działa, ale wymaga starannego planowania struktury projektu.  
- W praktyce przyspiesza kompilację o 2–3%, jak stwierdził "UserX".  
- Najlepsze wyniki daje w projektach z dużą liczbą wspólnych nagłówków i małą liczbą zmian w tych nagłówkach.  

Warto eksperymentować z lokalizacją tej dyrektywy i obserwować czas kompilacji, aby zoptymalizować pod kątem danego projektu.
P-182459
« 1 »
  Strona 1 z 1