Vorkompilierte Headerdateien

Wenn Sie ein neues Projekt in Visual Studio erstellen, wird dem Projekt eine vorkompilierte Headerdateipch.h hinzugefügt. (In Visual Studio 2017 und früher wurde die Datei als stdafx.h.) Der Zweck der Datei besteht darin, den Buildprozess zu beschleunigen. Alle stabilen Headerdateien, z. B. Standardbibliotheksheader wie <vector>, sollten hier eingefügt werden. Der vorkompilierte Header nur kompiliert, wenn er oder jegliche in ihm enthaltene Dateien geändert werden. Wenn Sie Änderungen am Quellcode Ihres Projekts vornehmen, überspringt der Buildprozess die Kompilierung des vorkompilierten Headers.

Die Compileroptionen für vorkompilierte Header sind /Y. Auf den Projekteigenschaftenseiten befinden sich die Optionen unter "Configuration PropertiesC>/C++>Precompiled Headers". Sie können sich dazu entscheiden, keine vorkompilierten Header zu verwenden, und den Headerdateinamen sowie den Namen und Pfad der Ausgabedatei festlegen.

Benutzerdefinierter vorkompilierter Code

Für große Projekte, deren Buildprozesse einige Zeit beanspruchen, sollten Sie das Erstellen benutzerdefinierter vorkompilierter Dateien in Erwägung ziehen. Die Microsoft C- und C++-Compiler stellen Optionen für das Vorkompilieren von beliebigem C- oder C++-Code bereit, einschließlich Inlinecode. Mithilfe dieses Leistungsfeatures können Sie einen stabilen Codetext kompilieren, den kompilierten Zustand des Codes in einer Datei speichern und während nachfolgenden Kompilierungen den vorkompilierten Code mit Code kombinieren, der noch in der Entwicklung liegt. Jede spätere Kompilierung ist schneller, da der stabile Code nicht neu kompiliert werden muss.

Wann vorkompiliertem Quellcode

Vorkompilierter Code ist während des Entwicklungsprozesses nützlich, um die Kompilierungszeit zu reduzieren. Dies gilt insbesondere in folgenden Fällen:

  • Sie verwenden immer umfangreiche Codeabschnitte, die häufig geändert werden.

  • Ihr Programm besteht aus mehreren Modulen, die alle eine Standardgruppe von Includedateien und die gleichen Kompilierungsoptionen verwenden. In diesem Fall können alle Dateien in einen vorkompilierten Header vorab kompiliert werden.

Die erste Kompilierung (die die vorkompilierte Headerdatei erstellt) dauert etwas länger als nachfolgende Kompilierungen. Nachfolgende Kompilierungen können schneller fortgesetzt werden, indem der vorkompilierte Code eingefügt wird.

Sie können sowohl C- als auch C++-Programme vorkompilieren. Bei der C++-Programmierung ist es üblich, Klassenschnittstelleninformationen in Headerdateien zu trennen. Diese Headerdateien können später in Programme eingefügt werden, die die Klasse verwenden. Indem Sie diese Header vorkompilieren, können Sie die Zeit reduzieren, die die Kompilierung eines Programms erfordert.

Hinweis

Obwohl Sie nur eine vorkompilierte Headerdatei (.pch) pro Quelldatei verwenden können, können Sie mehrere .pch Dateien in einem Projekt verwenden.

Zwei Optionen für den Vorkompilierungscode

Sie können einen beliebigen C- oder C++-Code vorkompilieren; Sie sind nicht auf das Kompilieren nur Kopfzeilendateien beschränkt.

Die Vorkompilierung erfordert Planung, jedoch bietet sie schnellere Kompilierungen, wenn Sie nicht nur einfache Headerdateien, sondern auch Quellcode vorkompilieren.

Kompilieren Sie Code vorab, wenn Sie wissen, dass Ihre Quelldateien die gleichen Headerdateien verwenden, diese aber nicht in der gleichen Reihenfolge enthalten, oder wenn Sie Quellcode in Ihre Vorkompilierung einfügen möchten.

Die Vorkompilierungsheaderoptionen sind /Yc (Vorkompilierte Headerdatei erstellen) und /Yu (Precompiled Header File verwenden). Wird verwendet /Yc , um einen vorkompilierten Header zu erstellen. Wenn Sie mit dem optionalen hdrstop Pragma verwendet werden, /Yc können Sie sowohl Headerdateien als auch Quellcode kompilieren. Wählen Sie /Yu aus, um einen vorhandenen vorkompilierten Header in der vorhandenen Kompilierung zu verwenden. Sie können auch /Fp mit den /Yc/Yu Optionen einen alternativen Namen für den vorkompilierten Header bereitstellen.

In den Compileroptionsreferenzartikeln /Yu/Yc wird erläutert, wie Sie auf diese Funktionalität in der Entwicklungsumgebung zugreifen können.

Vorkompilierte Headerkonsistenzregeln

Da PCH-Dateien Informationen über die Computerumgebung und Speicheradresseninformationen über das Programm enthalten, sollten Sie nur eine PCH-Datei auf dem Computer verwenden, auf dem sie erstellt wurde.

Konsistenzregeln für die Verwendung vorkompilierter Header

Mit der /Yu Compileroption können Sie angeben, welche PCH-Datei verwendet werden soll.

Wenn Sie eine PCH-Datei verwenden, geht der Compiler von derselben Kompilierungsumgebung aus (eine, die konsistente Compileroptionen, Pragmas usw.) verwendet, die beim Erstellen der PCH-Datei wirksam wurde, es sei denn, Sie geben andernfalls an. Wenn der Compiler eine Inkonsistenz erkennt, wird eine Warnung ausgegeben und die Inkonsistenz wird identifiziert, wenn möglich. Solche Warnungen weisen nicht unbedingt auf ein Problem mit der PCH-Datei hin. Sie dienen lediglich dazu, Sie vor möglichen Konflikten zu warnen. In den folgenden Abschnitten werden die Konsistenzanforderungen für PCH-Dateien behandelt.

Compileroptionskonsistenz

Die folgenden Compileroptionen können bei Verwendung einer PCH-Datei eine Inkonsistenzwarnung auslösen:

  • Makros, die mit der Option Preprocessor (/D) erstellt wurden, müssen identisch zwischen der Kompilierung sein, die die PCH-Datei und die aktuelle Kompilierung erstellt hat. Der Status definierter Konstanten ist nicht überprüft, aber unvorhersehbare Ergebnisse können auftreten, wenn sich diese Makros ändern.

  • PCH-Dateien funktionieren nicht mit den /E optionen /EP .

  • PCH-Dateien müssen mithilfe der Option "Browse Info generieren" (/FR) oder der Option "Lokale Variablen/Fr ausschließen" () erstellt werden, bevor nachfolgende Kompilierungen, die die PCH-Datei verwenden, diese Optionen verwenden können.

C 7.0-kompatible (/Z7)

Wenn diese Option wirksam ist, wenn die PCH-Datei erstellt wird, können spätere Kompilierungen, die die PCH-Datei verwenden, die Debuginformationen verwenden.

Wenn die Option C 7.0-Kompatible (/Z7) nicht wirksam ist, wenn die PCH-Datei erstellt wird, werden später Kompilierungen, die die PCH-Datei verwenden, erstellt und /Z7 eine Warnung ausgelöst. Die Debuginformationen werden in der aktuellen .obj Datei platziert, und lokale Symbole, die in der PCH-Datei definiert sind, sind für den Debugger nicht verfügbar.

Pfadkonsistenz einschließen

Eine PCH-Datei enthält keine Informationen über den Header, einschließlich Pfad, der beim Erstellen wirksam wurde. Wenn Sie eine PCH-Datei verwenden, verwendet der Compiler immer den in der aktuellen Kompilierung angegebenen Headerpfad.

Quelldateikonsistenz

Wenn Sie die Option "Vorkompilierte Headerdatei/Yu verwenden" () angeben, ignoriert der Compiler alle Präprozessordirektiven (einschließlich Pragmas), die im Quellcode angezeigt werden, der vorkompiliert wird. Die durch solche Präprozessordirektiven angegebene Kompilierung muss mit der Kompilierung identisch sein, die für die Option "Vorkompilierte Headerdatei erstellen" (/Yc) verwendet wird.

Pragma-Konsistenz

Pragmas, die während der Erstellung einer PCH-Datei verarbeitet wurden, wirken sich in der Regel auf die Datei aus, mit der die PCH-Datei später verwendet wird. Die comment und message Pragmas wirken sich nicht auf den Rest der Kompilierung aus.

Diese Pragmas wirken sich nur auf den Code in der PCH-Datei aus; sie wirken sich nicht auf Code aus, der später die PCH-Datei verwendet:

comment
linesize

message
page

pagesize
skip

subtitle
title

Die folgenden Pragmas werden als Teil eines vorkompilierten Headers beibehalten und wirken sich auf die restliche Kompilierung aus, die den vorkompilierten Header verwendet:

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

Konsistenzregeln für /Yc und /Yu

Wenn Sie einen vorkompilierten Header verwenden, der mithilfe /Yc oder /Yuerstellt wurde, vergleicht der Compiler die aktuelle Kompilierungsumgebung mit der, die beim Erstellen der PCH-Datei vorhanden ist. Stellen Sie sicher, dass Sie für die aktuelle Kompilierung eine Umgebung entsprechend der vorherigen festlegen (mithilfe konsistenter Compileroptionen, Pragmas usw.). Wenn der Compiler eine Inkonsistenz erkennt, wird eine Warnung ausgegeben und die Inkonsistenz wird identifiziert, wenn möglich. Solche Warnungen weisen nicht unbedingt auf ein Problem mit der PCH-Datei hin. Sie dienen lediglich dazu, Sie vor möglichen Konflikten zu warnen. In den folgenden Abschnitten werden die Konsistenzanforderungen für vorkompilierte Header erläutert.

Compileroptionskonsistenz

In dieser Tabelle werden die Compileroptionen aufgeführt, die eine Inkonsistenzwarnung auslösen könnten, wenn ein vorkompilierter Header verwendet wird:

Option name Regel
/D Define constants and macros (Konstanten und Makros definieren) Diese Option muss in der Kompilierung, in der der vorkompilierte Header erstellt wurde, und der aktuellen Kompilierung übereinstimmen. Der Status definierter Konstanten ist nicht aktiviert. Unvorhersehbare Ergebnisse können jedoch auftreten, wenn Ihre Dateien von den Werten der geänderten Konstanten abhängen.
/E oder /EP Copy preprocessor output to standard output (Präprozessorausgabe in Standardausgabe kopieren) Vorkompilierte Kopfzeilen funktionieren nicht mit der /E Option oder /EP der Option.
/Fr oder /FR Generate Microsoft Source Browser information (Microsoft-Quellbrowserinformationen generieren) Damit die /Fr/FR Optionen mit der /Yu Option gültig sind, müssen sie auch wirksam sein, wenn der vorkompilierte Header erstellt wurde. Nachfolgende Kompilierungen mit dem vorkompilierten Header generieren ebenfalls Quellbrowserinformationen. Browserinformationen werden in einer einzelnen .sbr Datei platziert und werden auf die gleiche Weise wie CodeView-Informationen referenziert. Sie können die Platzierung von Quellbrowserinformationen nicht außer Kraft setzen.
/GA, /GD, /GE, /Gw oder /GW Windows protocol options (Windows-Protokolloptionen) Diese Option muss in der Kompilierung, in der der vorkompilierte Header erstellt wurde, und der aktuellen Kompilierung übereinstimmen. Wenn sich diese Optionen unterscheiden, wird eine Warnmeldung ausgelöst.
/Zi Generate complete debugging information (Vollständige Debuginformationen generieren) Wenn diese Option bei Erstellung des vorkompilierten Headers aktiv ist, können nachfolgende Kompilierungen, die die Vorkompilierung verwenden, die Debuginformationen verwenden. Wenn /Zi der vorkompilierte Header nicht erstellt wird, werden nachfolgende Kompilierungen, die die Vorkompilierung verwenden, und die /Zi Option eine Warnung auslösen. Die Debuginformationen werden in der aktuellen Objektdatei platziert, und lokale Symbole, die im vorkompilierten Header definiert sind, sind für den Debugger nicht verfügbar.

Hinweis

Vorkompilierte Header sind nur zur Verwendung in C- und C++-Quelldateien vorgesehen.

Verwenden von vorab kompilierten Headern in einem Projekt

Die obigen Abschnitte veranschaulichen eine Übersicht über vorkompilierte Header: „/Yc“ und „/Yu“, die Option „/Fp“ und das Pragma hdrstop. In diesem Abschnitt wird eine Methode zur Verwendung der manuellen vorkompilierten Headeroptionen in einem Projekt beschrieben. Der Abschnitt endet mit einem Makefilebeispiel und dem Code, der durch dieses verwaltet wird.

Für einen anderen Ansatz zur Verwendung der manuellen Vorabheaderoptionen in einem Projekt untersuchen Sie eine der Makefiles im Verzeichnis, das während der MFC\SRC Standardeinrichtung von Visual Studio erstellt wurde. Diese Makefiles haben einen ähnlichen Ansatz wie in diesem Abschnitt dargestellt. Sie nutzen microsoft Program Maintenance Utility (NMAKE) Makros und bieten eine größere Kontrolle über den Buildprozess.

PCH-Dateien im Buildprozess

Die Codebasis eines Softwareprojekts ist häufig in mehreren C- oder C++-Quelldateien, Objektdateien, Bibliotheken und Headerdateien enthalten. Ein Makefile koordiniert in der Regel die Kombination dieser Elemente in eine ausführbare Datei. Die folgende Abbildung veranschaulicht die Struktur eines Makefile, das eine vorkompilierte Headerdatei verwendet. Die NMAKE-Makronamen und die Dateinamen in diesem Diagramm entsprechen den im Beispielcode gefundenen Beispielcode für PCH und Beispielcode für PCH.

In der Abbildung werden drei Diagrammelemente zum Veranschaulichen des Ablaufs des Buildprozesses verwendet. Beschriftete Rechtecke stellen einzelne Dateien oder Makros dar. Die drei Makros stellen eine oder mehrere Dateien dar. Schattierte Bereiche stellen Kompilierungs- oder Verknüpfungsaktionen dar. Die Pfeile geben an, welche Dateien und Makros während des Kompilierungs- oder Verknüpfungsprozesses kombiniert werden.

Diagram showing example inputs and outputs of a makefile that uses a precompiled header file.
Struktur eines Makefiles, das eine vorkompilierte Headerdatei verwendet

Beginnend am oberen Rand des Diagramms sind sowohl STABLEHDRSBOUNDRY NMAKE-Makros als auch NMAKE-Makros, in denen Sie Dateien auflisten, die nicht wahrscheinlich erneut kompiliert werden müssen. Diese Dateien werden nur von der Befehlszeichenfolge

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

nur, wenn die vorab kompilierte Kopfzeilendatei (STABLE.pch) nicht vorhanden ist oder Wenn Sie Änderungen an den dateien vornehmen, die in den beiden Makros aufgeführt sind. In beiden Fällen enthält die vorab kompilierte Kopfzeilendatei nur Code aus den Dateien, die im STABLEHDRS Makro aufgeführt sind. Listen Sie die letzte Datei auf, die Sie im BOUNDRY Makro vorab kompiliert haben möchten.

Bei den Dateien, die Sie in diesen Makros aufführen, kann es sich entweder um Headerdateien oder C- bzw. C++-Quelldateien handeln. (Eine einzelne PCH-Datei kann nicht mit C- und C++-Quellen verwendet werden.) Sie können das hdrstop Makro verwenden, um die Vorabkompilierung an einem bestimmten Punkt innerhalb der BOUNDRY Datei zu beenden. Weitere Informationen finden Sie unter hdrstop.

Als Nächstes im Diagramm wird der Supportcode dargestellt, APPLIB.obj der in Ihrer endgültigen Anwendung verwendet wird. Es wird aus APPLIB.cpp, den Dateien, die im Makro aufgeführt sind, und vorkompiliertem Code aus dem UNSTABLEHDRS vorab kompilierten Header erstellt.

MYAPP.obj stellt Ihre endgültige Anwendung dar. Es wird aus MYAPP.cpp, den Dateien, die im Makro aufgeführt sind, und vorkompiliertem Code aus dem UNSTABLEHDRS vorab kompilierten Header erstellt.

Schließlich wird die ausführbare Datei () erstellt, indem Sie die dateien verknüpfen, die im OBJS MakroAPPLIB.obj (MYAPP.EXEund MYAPP.obj) aufgeführt sind.

Beispiel-Makefile für PCH

Im folgenden Makefile werden Makros und eine !IF!ELSE, !ENDIF Fluss-of-Control-Befehlsstruktur verwendet, um die Anpassung an Ihr Projekt zu vereinfachen.

# 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

Neben den STABLEHDRSBOUNDRYin der Abbildung "Struktur einer Makefile, die eine vorab kompilierte Kopfzeilendatei verwendet" in PCH-Dateien im Buildprozess gezeigten Makros LINKFLAGS und UNSTABLEHDRS Makros.CLFLAGS Sie müssen diese Makros verwenden, um Compiler- und Linkeroptionen aufzulisten, die unabhängig davon angewendet werden, ob Sie eine Debugversion oder die endgültige Version der ausführbaren Datei erstellen. Es gibt auch ein LIBS Makro, in dem Sie die Bibliotheken auflisten, die Ihr Projekt benötigt.

Die Makefile verwendet !IFauch , !ELSE!ENDIF um zu erkennen, ob Sie ein DEBUG Symbol in der NMAKE-Befehlszeile definieren:

NMAKE DEBUG=[1|0]

Dieses Feature ermöglicht es Ihnen, die gleiche Makefile während der Entwicklung und für die endgültigen Versionen Ihres Programms zu verwenden. Verwenden Sie DEBUG=0 für die endgültigen Versionen. Die folgenden Befehlszeilen sind gleichwertig:

NMAKE
NMAKE DEBUG=0

Weitere Informationen zu Makefiles finden Sie unter NMAKE-Referenz. Weitere Informationen finden Sie unter MSVC Compileroptionen und den MSVC Linkeroptionen.

Beispielcode für PCH

Die folgenden Quelldateien werden in den in PCH-Dateien beschriebenen Makefiles im Buildprozess und sample makefile für PCH verwendet. Die Kommentare enthalten wichtige Informationen.

// 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.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.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.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.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();
}

Siehe auch

Referenz zur C/C++-Erstellung
MSVC Compileroptionen