Condividi tramite


File di intestazione precompilati

Quando si crea un nuovo progetto in Visual Studio, viene aggiunto un file di intestazione precompilato denominato pch.h al progetto. In Visual Studio 2017 e versioni precedenti il file è stato chiamato stdafx.h.) Lo scopo del file è velocizzare il processo di compilazione. Tutti i file di intestazione stabili, ad esempio le intestazioni della libreria standard, <vector>ad esempio , devono essere inclusi qui. L'intestazione precompilata viene compilata solo quando viene modificata o i file inclusi. Se si apportano modifiche solo nel codice sorgente del progetto, la compilazione salterà la compilazione per l'intestazione precompilata.

Le opzioni del compilatore per le intestazioni precompilate sono /Y. Nelle pagine delle proprietà del progetto le opzioni si trovano in Proprietà>di configurazione C/C++>Intestazioni precompilate. È possibile scegliere di non usare intestazioni precompilate ed è possibile specificare il nome del file di intestazione e il nome e il percorso del file di output.

Codice precompilato personalizzato

Per progetti di grandi dimensioni che richiedono molto tempo per la compilazione, è consigliabile creare file precompilati personalizzati. I compilatori Microsoft C e C++ includono opzioni per la precompilazione di codice C o C++ di qualsiasi tipo, incluso quello inline. Usando questa funzionalità di prestazioni, è possibile compilare un corpo stabile del codice, archiviare lo stato compilato del codice in un file e, durante le compilazioni successive, combinare il codice precompilato con il codice ancora in fase di sviluppo. Ogni compilazione successiva è più veloce perché non è necessario ricompilare il codice stabile.

Quando precompilare il codice sorgente

Il codice precompilato è utile durante il ciclo di sviluppo per ridurre il tempo di compilazione, soprattutto se:

  • Si usa sempre un corpo di codice di grandi dimensioni che cambia raramente.

  • Il programma comprende più moduli, tutti che usano un set standard di file di inclusione e le stesse opzioni di compilazione. In questo caso, tutti i file di inclusione possono essere precompilati in un'unica intestazione precompilata. Per altre informazioni sui modi più recenti per gestire i file di inclusione, vedere Confrontare unità di intestazione, moduli e intestazioni precompilate.

La prima compilazione (quella che crea il file di intestazione precompilato) richiede un po' di tempo rispetto alle compilazioni successive. Le compilazioni successive possono procedere più rapidamente includendo il codice precompilato.

È possibile precompilare programmi C e C++. Nella programmazione C++ è pratica comune separare le informazioni sull'interfaccia della classe nei file di intestazione. Questi file di intestazione possono essere inclusi in un secondo momento nei programmi che usano la classe . Precompilando queste intestazioni, è possibile ridurre il tempo necessario per la compilazione di un programma.

Nota

Sebbene sia possibile usare un solo file di intestazione precompilata (.pch) per ogni file di origine, è possibile usare più .pch file in un progetto.

Due opzioni per la precompilazione del codice

È possibile precompilare qualsiasi codice C o C++; non è limitato alla precompilazione solo dei file di intestazione.

La precompilazione richiede la pianificazione, ma offre compilazioni molto più veloci se si precompila il codice sorgente diverso dai file di intestazione semplici.

Precompilare il codice quando si sa che i file di origine usano set comuni di file di intestazione o quando si vuole includere il codice sorgente nella precompilazione.

Le opzioni precompilate-header sono /Yc (Crea file di intestazione precompilato) e /Yu (Usa file di intestazione precompilato). Usare /Yc per creare un'intestazione precompilata. Se usato con il pragma facoltativo hdrstop , /Yc consente di precompilare sia i file di intestazione che il codice sorgente. Selezionare questa opzione /Yu per usare un'intestazione precompilata esistente nella compilazione esistente. È anche possibile usare /Fp con le /Yc opzioni e /Yu per specificare un nome alternativo per l'intestazione precompilata.

Gli articoli di riferimento sulle opzioni del compilatore per /Yu e /Yc illustrano come accedere a questa funzionalità nell'ambiente di sviluppo.

Regole di coerenza delle intestazioni precompilate

Poiché i file PCH contengono informazioni sull'ambiente del computer e sull'indirizzo di memoria relativi al programma, è consigliabile usare solo un file PCH nel computer in cui è stato creato.

Regole di coerenza per l'uso per file di intestazioni precompilate

L'opzione /Yu del compilatore consente di specificare il file PCH da usare.

Quando si usa un file PCH, il compilatore presuppone lo stesso ambiente di compilazione effettivo quando è stato creato il file PCH, a meno che non si specifichi diversamente. L'ambiente di compilazione include le opzioni del compilatore, i pragmas e così via. Se il compilatore rileva un'incoerenza, genera un avviso e identifica l'incoerenza laddove possibile. Tali avvisi non indicano necessariamente un problema con il file PCH; ti avvertono semplicemente dei possibili conflitti. I requisiti di coerenza per i file PCH sono descritti nelle sezioni seguenti.

Coerenza delle opzioni del compilatore

Le opzioni del compilatore seguenti possono attivare un avviso di incoerenza quando si usa un file PCH:

  • Le macro create usando l'opzione Preprocessore (/D) devono essere uguali tra la compilazione che ha creato il file PCH e la compilazione corrente. Lo stato delle costanti definite non viene controllato, ma i risultati imprevedibili possono verificarsi se queste macro cambiano.

  • I file PCH non funzionano con le /E opzioni e /EP .

  • I file PCH devono essere creati usando l'opzione Genera informazioni sfoglia (/FR) o l'opzione Escludi variabili locali (/Fr) prima che le compilazioni successive che utilizzano il file PCH possano usare queste opzioni.

Compatibile con C 7.0 (/Z7)

Se questa opzione è attiva quando viene creato il file PCH, le compilazioni successive che usano il file PCH possono usare le informazioni di debug.

Se l'opzione C 7.0-Compatible (/Z7) non è attiva quando viene creato il file PCH, le compilazioni successive che usano il file PCH e /Z7 attivano un avviso. Le informazioni di debug vengono inserite nel file corrente .obj e i simboli locali definiti nel file PCH non sono disponibili per il debugger.

Includere la coerenza del percorso

Un file PCH non contiene informazioni sull'intestazione include percorso attivo al momento della creazione. Quando si usa un file PCH, il compilatore usa sempre il percorso di inclusione dell'intestazione specificato nella compilazione corrente.

Coerenza dei file di origine

Quando si specifica l'opzione Usa file di intestazione precompilato (/Yu), il compilatore ignora tutte le direttive del preprocessore (inclusi i pragmas) visualizzate nel codice sorgente che verranno precompilate. La compilazione specificata da tali direttive del preprocessore deve corrispondere alla compilazione usata per l'opzione Create Precompiled Header File (/Yc).

Coerenza pragma

I pragmas elaborati durante la creazione di un file PCH in genere influiscono sul file con cui il file PCH viene usato in un secondo momento. I comment pragma e message non influiscono sul resto della compilazione.

Questi pragma influiscono solo sul codice all'interno del file PCH; non influiscono sul codice che in seguito usa il file PCH:

comment
linesize

message
page

pagesize
skip

subtitle
title

Questi pragma vengono conservati come parte di un'intestazione precompilata e influiscono sul resto di una compilazione che usa l'intestazione precompilata:

alloc_text
auto_inline
check_stack
code_seg
data_seg

function
include_alias
init_seg
inline_depth

inline_recursion
intrinsic
optimize
pack

pointers_to_members
setlocale
vtordisp
warning

Regole di coerenza per /Yc e /Yu

Quando si usa un'intestazione precompilata creata usando /Yc o /Yu, il compilatore confronta l'ambiente di compilazione corrente con quello esistente durante la creazione del file PCH. Assicurarsi di specificare un ambiente coerente con quello precedente (usando opzioni del compilatore coerenti, pragma e così via) per la compilazione corrente. Se il compilatore rileva un'incoerenza, genera un avviso e identifica l'incoerenza laddove possibile. Tali avvisi non indicano necessariamente un problema con il file PCH; ti avvertono semplicemente dei possibili conflitti. Le sezioni seguenti illustrano i requisiti di coerenza per le intestazioni precompilate.

Coerenza delle opzioni del compilatore

Questa tabella elenca le opzioni del compilatore che potrebbero attivare un avviso di incoerenza quando si usa un'intestazione precompilata:

Opzione Nome Regola
/D Definire costanti e macro Deve essere uguale tra la compilazione che ha creato l'intestazione precompilata e la compilazione corrente. Lo stato delle costanti definite non viene controllato. Tuttavia, i risultati imprevedibili possono verificarsi se i file dipendono dai valori delle costanti modificate.
/E oppure /EP Copiare l'output del preprocessore nell'output standard Le intestazioni precompilate non funzionano con l'opzione /E o /EP .
/Fr oppure /FR Generare informazioni sul browser di origine Microsoft Affinché le /Fr opzioni e /FR siano valide con l'opzione /Yu , devono essere valide anche quando è stata creata l'intestazione precompilata. Le compilazioni successive che usano l'intestazione precompilata generano anche informazioni sul browser di origine. Le informazioni del browser vengono inserite in un singolo .sbr file e fanno riferimento ad altri file nello stesso modo delle informazioni di CodeView. Non è possibile eseguire l'override del posizionamento delle informazioni del browser di origine.
/GA, /GD, /GE, /Gw o /GW Opzioni del protocollo Di Windows Deve essere uguale tra la compilazione che ha creato l'intestazione precompilata e la compilazione corrente. Il compilatore genera un avviso se queste opzioni sono diverse.
/Zi Generare informazioni di debug complete Se questa opzione è attiva quando viene creata l'intestazione precompilata, le compilazioni successive che usano la precompilazione possono usare tali informazioni di debug. Se /Zi non è attivo quando viene creata l'intestazione precompilata, le compilazioni successive che usano la precompilazione e l'opzione /Zi attivano un avviso. Le informazioni di debug vengono inserite nel file oggetto corrente e i simboli locali definiti nell'intestazione precompilata non sono disponibili per il debugger.

Nota

La funzionalità di intestazione precompilata è destinata all'uso solo nei file di origine C e C++.

Uso di intestazioni precompilate in un progetto

Le sezioni precedenti presentano una panoramica delle intestazioni precompilate: /Yc e /Yu, l'opzione /Fp e il pragma hdrstop . Questa sezione descrive un metodo per l'uso delle opzioni manuali precompilate-header in un progetto; termina con un makefile di esempio e il codice gestito.

Per un altro approccio all'uso delle opzioni manuali di intestazione precompilata in un progetto, esaminare uno dei makefile presenti nella MFC\SRC directory creata durante la configurazione predefinita di Visual Studio. Questi makefile accettano un approccio simile a quello presentato in questa sezione. Usano maggiormente le macro di Utilità di manutenzione programma Microsoft (NMAKE) e offrono un maggiore controllo del processo di compilazione.

File PCH nel processo di compilazione

La codebase di un progetto software è spesso contenuta in più file di origine C o C++, file oggetto, librerie e file di intestazione. In genere, un makefile coordina la combinazione di questi elementi in un file eseguibile. Nella figura seguente viene illustrata la struttura di un makefile che usa un file di intestazione precompilato. I nomi delle macro NMAKE e i nomi di file in questo diagramma sono coerenti con il codice di esempio trovato in Makefile di esempio per PCH e codice di esempio per PCH.

La figura usa tre dispositivi diagrammatici per mostrare il flusso del processo di compilazione. I rettangoli denominati rappresentano ogni file o macro; le tre macro rappresentano uno o più file. Le aree ombreggiate rappresentano ogni azione di compilazione o collegamento. Le frecce mostrano quali file e macro vengono combinati durante il processo di compilazione o collegamento.

 Il diagramma è descritto nel testo che segue il diagramma.
Struttura di un makefile che usa un file di intestazione precompilato:

Diagramma che mostra input e output di esempio di un makefile che usa un file di intestazione precompilato.

Il diagramma mostra '$(STABLEHDRS)' e '$(BOUNDRY)' che si inserisce in CL /c /W3 /Yc$(BOUNDRY) applib.cpp myapp.cpp. Output di $(STABLE. PCH). Quindi, applib.cpp e $(UNSTABLEHDRS) e $(STABLE. FEED PCH) in CL /c /w3 /Yu $(BOUNDRY) applib.cpp, che produce applib.obj. myapp.cpp, $(UNSTABLEHDR) e $(STABLE. Feed PCH) in CL /c /w3 /Yu $(BOUNDRY) myapp.cpp, che produce myapp.obj. Infine, applib.obj e myapp.obj vengono combinati da LINK /NOD ONERROR:NOEXE $(OBJS), myapp, NUL, $(LIBS), NUL per produrre myapp.exe.

A partire dalla parte superiore del diagramma, entrambe STABLEHDRS e BOUNDRY sono macro NMAKE in cui è probabile che i file non debbano essere ricompilazione. Questi file vengono compilati dalla stringa di comando

CL /c /W3 /Yc$(BOUNDRY) applib.cpp myapp.cpp

solo se il file di intestazione precompilato (STABLE.pch) non esiste o se si apportano modifiche ai file elencati nelle due macro. In entrambi i casi, il file di intestazione precompilato conterrà codice solo dai file elencati nella STABLEHDRS macro. Elencare l'ultimo file che si desidera precompilare nella BOUNDRY macro.

I file elencati in queste macro possono essere file di intestazione o file di origine C o C++. Non è possibile usare un singolo file PCH con origini C e C++. È possibile utilizzare la macro per arrestare la hdrstop precompilazione in un determinato punto all'interno del BOUNDRY file. Per ulteriori informazioni, vedere hdrstop.

Successivamente, nel diagramma, APPLIB.obj rappresenta il codice di supporto usato nell'applicazione finale. Viene creato da APPLIB.cpp, i file elencati nella UNSTABLEHDRS macro e il codice precompilato dall'intestazione precompilata.

MYAPP.obj rappresenta l'applicazione finale. Viene creato da MYAPP.cpp, i file elencati nella UNSTABLEHDRS macro e il codice precompilato dall'intestazione precompilata.

Infine, il file eseguibile (MYAPP.EXE) viene creato collegando i file elencati nella OBJS macro (APPLIB.obj e MYAPP.obj).

Makefile di esempio per PCH

Il makefile seguente usa macro e una !IFstruttura di comandi , !ELSE, flow-of-control !ENDIF per semplificare l'adattamento al progetto.

# Makefile : Illustrates the effective use of precompiled
#            headers in a project
# Usage:     NMAKE option
# option:    DEBUG=[0|1]
#            (DEBUG not defined is equivalent to DEBUG=0)
#
OBJS = myapp.obj applib.obj
# List all stable header files in the STABLEHDRS macro.
STABLEHDRS = stable.h another.h
# List the final header file to be precompiled here:
BOUNDRY = stable.h
# List header files under development here:
UNSTABLEHDRS = unstable.h
# List all compiler options common to both debug and final
# versions of your code here:
CLFLAGS = /c /W3
# List all linker options common to both debug and final
# versions of your code here:
LINKFLAGS = /nologo
!IF "$(DEBUG)" == "1"
CLFLAGS   = /D_DEBUG $(CLFLAGS) /Od /Zi
LINKFLAGS = $(LINKFLAGS) /COD
LIBS      = slibce
!ELSE
CLFLAGS   = $(CLFLAGS) /Oselg /Gs
LINKFLAGS = $(LINKFLAGS)
LIBS      = slibce
!ENDIF
myapp.exe: $(OBJS)
    link $(LINKFLAGS) @<<
$(OBJS), myapp, NUL, $(LIBS), NUL;
<<
# Compile myapp
myapp.obj  : myapp.cpp $(UNSTABLEHDRS)  stable.pch
    $(CPP) $(CLFLAGS) /Yu$(BOUNDRY)    myapp.cpp
# Compile applib
applib.obj : applib.cpp $(UNSTABLEHDRS) stable.pch
    $(CPP) $(CLFLAGS) /Yu$(BOUNDRY)    applib.cpp
# Compile headers
stable.pch : $(STABLEHDRS)
    $(CPP) $(CLFLAGS) /Yc$(BOUNDRY)    applib.cpp myapp.cpp

A parte le STABLEHDRSmacro , BOUNDRYe UNSTABLEHDRS illustrate nella figura "Struttura di un makefile che usa un file di intestazione precompilato" nei file PCH del processo di compilazione, questo makefile fornisce una CLFLAGS macro e una LINKFLAGS macro. È necessario utilizzare queste macro per elencare le opzioni del compilatore e del linker che si applicano se si compila una versione di debug o finale del file eseguibile dell'applicazione. È disponibile anche una LIBS macro in cui sono elencate le librerie richieste dal progetto.

Il makefile usa !IFanche , !ELSE, !ENDIF per rilevare se si definisce un DEBUG simbolo nella riga di comando di NMAKE:

NMAKE DEBUG=[1|0]

Questa funzionalità consente di usare lo stesso makefile durante lo sviluppo e per le versioni finali del programma. Usare DEBUG=0 per le versioni finali. Le righe di comando indicate di seguito sono equivalenti:

NMAKE
NMAKE DEBUG=0

Per altre informazioni sui makefile, vedere Informazioni di riferimento su NMAKE. Vedere anche opzioni del compilatore MSVC e le opzioni del linker MSVC.

Codice di esempio per PCH

I file di origine seguenti vengono usati nel makefile descritto nei file PCH nel processo di compilazione e nel makefile di esempio per PCH. I commenti contengono informazioni importanti.

ANOTHER.HFile di origine :

// ANOTHER.H : Contains the interface to code that is not
//             likely to change.
//
#ifndef __ANOTHER_H
#define __ANOTHER_H
#include<iostream>
void savemoretime( void );
#endif // __ANOTHER_H

STABLE.HFile di origine :

// STABLE.H : Contains the interface to code that is not likely
//            to change. List code that is likely to change
//            in the makefile's STABLEHDRS macro.
//
#ifndef __STABLE_H
#define __STABLE_H
#include<iostream>
void savetime( void );
#endif // __STABLE_H

UNSTABLE.HFile di origine :

// UNSTABLE.H : Contains the interface to code that is
//              likely to change. As the code in a header
//              file becomes stable, remove the header file
//              from the makefile's UNSTABLEHDR macro and list
//              it in the STABLEHDRS macro.
//
#ifndef __UNSTABLE_H
#define __UNSTABLE_H
#include<iostream>
void notstable( void );
#endif // __UNSTABLE_H

APPLIB.CPPFile di origine :

// APPLIB.CPP : This file contains the code that implements
//              the interface code declared in the header
//              files STABLE.H, ANOTHER.H, and UNSTABLE.H.
//
#include"another.h"
#include"stable.h"
#include"unstable.h"
using namespace std;
// The following code represents code that is deemed stable and
// not likely to change. The associated interface code is
// precompiled. In this example, the header files STABLE.H and
// ANOTHER.H are precompiled.
void savetime( void )
    { cout << "Why recompile stable code?\n"; }
void savemoretime( void )
    { cout << "Why, indeed?\n\n"; }
// The following code represents code that is still under
// development. The associated header file is not precompiled.
void notstable( void )
    { cout << "Unstable code requires"
            << " frequent recompilation.\n";
    }

MYAPP.CPPFile di origine :

// MYAPP.CPP : Sample application
//             All precompiled code other than the file listed
//             in the makefile's BOUNDRY macro (stable.h in
//             this example) must be included before the file
//             listed in the BOUNDRY macro. Unstable code must
//             be included after the precompiled code.
//
#include"another.h"
#include"stable.h"
#include"unstable.h"
int main( void )
{
    savetime();
    savemoretime();
    notstable();
}

Vedi anche

Confrontare unità di intestazione, moduli e intestazioni precompilate
Riferimenti alla compilazione in C/C++
Opzionidel compilatore MSVC Panoramica dei moduli in C++
Esercitazione: Importare la libreria standard C++ usando i moduli
Procedura dettagliata: Compilare e importare unità di intestazione nei progetti Visual C++
Procedura dettagliata: Importare librerie STL come unità di intestazione