Partilhar via


Arquivos de cabeçalho pré-compilados

Quando você cria um novo projeto no Visual Studio, um arquivo de cabeçalho pré-compilado nomeado pch.h é adicionado ao projeto. (No Visual Studio 2017 e anteriores, o arquivo foi chamado stdafx.h.) O objetivo do arquivo é acelerar o processo de compilação. Todos os arquivos de cabeçalho estáveis, por exemplo, cabeçalhos de biblioteca padrão, como <vector>, devem ser incluídos aqui. O cabeçalho pré-compilado é compilado somente quando ele, ou quaisquer arquivos que ele inclui, são modificados. Se apenas fizer alterações no código-fonte do projeto, a compilação ignorará o cabeçalho pré-compilado.

As opções do compilador para cabeçalhos pré-compilados são /Y. Nas páginas de propriedades do projeto, as opções estão localizadas em Propriedades >C/C++>Cabeçalhos pré-compilados. Você pode optar por não usar cabeçalhos pré-compilados e pode especificar o nome do arquivo de cabeçalho e o nome e o caminho do arquivo de saída.

Código pré-compilado personalizado

Para projetos grandes que levam tempo significativo para serem criados, convém considerar a criação de arquivos pré-compilados personalizados. Os compiladores Microsoft C e C++ fornecem opções para pré-compilar qualquer código C ou C++, incluindo código embutido. Usando esse recurso de desempenho, você pode compilar um corpo estável de código, armazenar o estado compilado do código em um arquivo e, durante compilações subsequentes, combinar o código pré-compilado com o código que ainda está em desenvolvimento. Cada compilação posterior é mais rápida porque o código estável não precisa ser recompilado.

Quando pré-compilar o código-fonte

O código pré-compilado é útil durante o ciclo de desenvolvimento para reduzir o tempo de compilação, especialmente se:

  • Você sempre usa um grande corpo de código que muda com pouca frequência.

  • Seu programa é composto por vários módulos, todos os quais usam um conjunto padrão de arquivos de inclusão e as mesmas opções de compilação. Nesse caso, todos os arquivos de inclusão podem ser pré-compilados em um cabeçalho pré-compilado. Para obter mais informações sobre maneiras mais recentes de manipular arquivos de inclusão, consulte Comparar unidades de cabeçalho, módulos e cabeçalhos pré-compilados.

A primeira compilação (aquela que cria o arquivo de cabeçalho pré-compilado) leva um pouco mais de tempo do que as compilações subsequentes. As compilações subsequentes podem prosseguir mais rapidamente incluindo o código pré-compilado.

Você pode pré-compilar programas C e C++. Na programação C++, é prática comum separar as informações da interface de classe em arquivos de cabeçalho. Esses arquivos de cabeçalho podem ser incluídos posteriormente em programas que usam a classe. Ao pré-compilar esses cabeçalhos, você pode reduzir o tempo que um programa leva para compilar.

Observação

Embora você possa usar apenas um arquivo de cabeçalho (.pch) pré-compilado por arquivo de origem, você pode usar vários .pch arquivos em um projeto.

Duas opções para pré-compilação de código

Você pode pré-compilar qualquer código C ou C++; Você não está limitado a pré-compilar apenas arquivos de cabeçalho.

A pré-compilação requer planejamento, mas oferece compilações muito mais rápidas se você pré-compilar código-fonte diferente de arquivos de cabeçalho simples.

Pré-compile o código quando souber que seus arquivos de origem usam conjuntos comuns de arquivos de cabeçalho ou quando quiser incluir o código-fonte em sua pré-compilação.

As opções de cabeçalho pré-compilado são /Yc (Criar arquivo de cabeçalho pré-compilado) e /Yu (Usar arquivo de cabeçalho pré-compilado). Use /Yc para criar um cabeçalho pré-compilado. Quando usado com o pragma opcional hdrstop , /Yc permite pré-compilar arquivos de cabeçalho e código-fonte. Selecione /Yu para usar um cabeçalho pré-compilado existente na compilação existente. Você também pode usar /Fp com as /Yc opções e /Yu para fornecer um nome alternativo para o cabeçalho pré-compilado.

Os artigos de referência da opção do compilador para /Yu e /Yc discutem como aceder a esta funcionalidade no ambiente de desenvolvimento.

Regras de consistência de cabeçalho pré-compiladas

Como os arquivos PCH contêm informações sobre o ambiente da máquina e informações de endereço de memória sobre o programa, você só deve usar um arquivo PCH na máquina onde ele foi criado.

Regras de consistência para uso por arquivo de cabeçalhos pré-compilados

A /Yu opção de compilador permite especificar qual arquivo PCH usar.

Quando você usa um arquivo PCH, o compilador assume o mesmo ambiente de compilação que estava em vigor quando você criou o arquivo PCH, a menos que você especifique o contrário. O ambiente de compilação inclui as opções do compilador, pragmas e assim por diante. Se o compilador detetar uma inconsistência, ele emitirá um aviso e identificará a inconsistência sempre que possível. Tais avisos não indicam necessariamente um problema com o arquivo PCH; eles simplesmente avisam sobre possíveis conflitos. Os requisitos de consistência para arquivos PCH são descritos nas seções a seguir.

Consistência da opção do compilador

As seguintes opções do compilador podem disparar um aviso de inconsistência ao usar um arquivo PCH:

  • As macros criadas usando a opção Pré-processador (/D) devem ser as mesmas entre a compilação que criou o arquivo PCH e a compilação atual. O estado das constantes definidas não é verificado, mas resultados imprevisíveis podem ocorrer se essas macros forem alteradas.

  • Os arquivos PCH não funcionam com /E e /EP opções.

  • Os arquivos PCH devem ser criados usando a opção Gerar informações de navegação (/FR) ou a opção Excluir variáveis locais (/Fr) antes que compilações subsequentes que usam o arquivo PCH possam usar essas opções.

Compatível com C 7.0 (/Z7)

Se essa opção estiver em vigor quando o arquivo PCH for criado, compilações posteriores que usam o arquivo PCH podem usar as informações de depuração.

Se a opção C 7.0-Compatible (/Z7) não estiver em efeito quando o ficheiro PCH for criado, compilações posteriores que utilizam o ficheiro PCH e /Z7 acionam um aviso. As informações de depuração são colocadas no arquivo atual .obj e os símbolos locais definidos no arquivo PCH não estão disponíveis para o depurador.

Incluir consistência de caminho

Um arquivo PCH não contém informações sobre o caminho de inclusão de cabeçalho que estava em vigor quando foi criado. Quando você usa um arquivo PCH, o compilador sempre usa o caminho de inclusão do cabeçalho especificado na compilação atual.

Consistência do arquivo de origem

Quando você especifica a opção Usar arquivo de cabeçalho pré-compilado (/Yu), o compilador ignora todas as diretivas de pré-processador (incluindo pragmas) que aparecem no código-fonte que será pré-compilado. A compilação especificada por tais diretivas de pré-processador deve ser a mesma que a compilação usada para a opção Criar arquivo de cabeçalho pré-compilado (/Yc).

Consistência do Pragma

Pragmas processados durante a criação de um arquivo PCH geralmente afetam o arquivo com o qual o arquivo PCH é usado posteriormente. O comment e message pragmas não afetam o restante da compilação.

Esses pragmas afetam apenas o código dentro do arquivo PCH; eles não afetam o código que mais tarde usa o arquivo PCH:

comment
linesize

message
page

pagesize
skip

subtitle
title

Esses pragmas são mantidos como parte de um cabeçalho pré-compilado e afetam o restante de uma compilação que usa o cabeçalho pré-compilado:

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

Regras de coerência para /Yc e /Yu

Quando você usa um cabeçalho pré-compilado criado usando /Yc ou /Yu, o compilador compara o ambiente de compilação atual com o que existia quando você criou o arquivo PCH. Certifique-se de especificar um ambiente consistente com o anterior (usando opções consistentes do compilador, pragmas e assim por diante) para a compilação atual. Se o compilador detetar uma inconsistência, ele emitirá um aviso e identificará a inconsistência sempre que possível. Tais avisos não indicam necessariamente um problema com o arquivo PCH; eles simplesmente avisam sobre possíveis conflitos. As seções a seguir explicam os requisitos de consistência para cabeçalhos pré-compilados.

Consistência da opção do compilador

Esta tabela lista as opções do compilador que podem disparar um aviso de inconsistência ao usar um cabeçalho pré-compilado:

Opção Nome Regra
/D Definir constantes e macros Deve ser o mesmo entre a compilação que criou o cabeçalho pré-compilado e a compilação atual. O estado das constantes definidas não é verificado. No entanto, resultados imprevisíveis podem ocorrer se seus arquivos dependerem dos valores das constantes alteradas.
/E ou /EP Copiar a saída do pré-processador para a saída padrão Os cabeçalhos pré-compilados não funcionam com as opções /E ou /EP.
/Fr ou /FR Gerar informações do Microsoft Source Browser Para que as /Fr opções e /FR sejam válidas com a /Yu opção, elas também devem estar em vigor quando o cabeçalho pré-compilado foi criado. As compilações subsequentes que usam o cabeçalho pré-compilado também geram informações do navegador de origem. As informações do navegador são colocadas em um único .sbr arquivo e são referenciadas por outros arquivos da mesma maneira que as informações do CodeView. Não é possível substituir o posicionamento das informações do navegador de origem.
/GA, /GD, /GE, /Gwou /GW Opções de protocolo do Windows Deve ser o mesmo entre a compilação que criou o cabeçalho pré-compilado e a compilação atual. O compilador emite um aviso se essas opções forem diferentes.
/Zi Gerar informações completas de depuração Se essa opção estiver em vigor quando o cabeçalho pré-compilado for criado, as compilações subsequentes que usam a pré-compilação poderão usar essas informações de depuração. Se /Zi não estiver em vigor quando o cabeçalho pré-compilado for criado, as compilações subsequentes que usam a pré-compilação e a /Zi opção disparam um aviso. As informações de depuração são colocadas no arquivo de objeto atual e os símbolos locais definidos no cabeçalho pré-compilado não estão disponíveis para o depurador.

Observação

O recurso de cabeçalho pré-compilado destina-se ao uso somente em arquivos de origem C e C++.

Usando cabeçalhos pré-compilados em um projeto

As seções anteriores apresentam uma visão geral dos cabeçalhos pré-compilados: /Yc e /Yu, a opção /Fp e o pragma hdrstop . Esta seção descreve um método para usar as opções manuais de cabeçalho pré-compilado em um projeto; ele termina com um exemplo makefile e o código que ele gerencia.

Para outra abordagem para usar as opções manuais de cabeçalho pré-compilado em um projeto, estude um dos makefiles localizados no MFC\SRC diretório criado durante a instalação padrão do Visual Studio. Esses makefiles adotam uma abordagem semelhante à apresentada nesta seção. Eles fazem maior uso de macros do Microsoft Program Maintenance Utility (NMAKE) e oferecem maior controle do processo de compilação.

Arquivos PCH no processo de compilação

A base de código de um projeto de software geralmente está contida em vários arquivos de origem C ou C++, arquivos de objeto, bibliotecas e arquivos de cabeçalho. Normalmente, um makefile coordena a combinação desses elementos em um arquivo executável. A figura a seguir mostra a estrutura de um makefile que usa um arquivo de cabeçalho pré-compilado. Os nomes de macro NMAKE e os nomes de arquivo neste diagrama são consistentes com o código de exemplo encontrado em makefile de exemplo para PCH e código de exemplo para PCH.

A figura usa três dispositivos diagramáticos para mostrar o fluxo do processo de construção. Os retângulos nomeados representam cada arquivo ou macro; As três macros representam um ou mais arquivos. As áreas sombreadas representam cada ação de compilação ou link. As setas mostram quais arquivos e macros são combinados durante o processo de compilação ou vinculação.

Estrutura de um makefile que usa um arquivo de cabeçalho pré-compilado:

Diagrama mostrando exemplos de entradas e saídas de um makefile que usa um arquivo de cabeçalho pré-compilado.

O diagrama mostra '$(STABLEHDRS)' e '$(BOUNDRY)' alimentando CL /c /W3 /Yc$(BOUNDRY) applib.cpp myapp.cpp. A saída disso é $(STABLE.PCH). Em seguida, applib.cpp e $(UNSTABLEHDRS) e $(STABLE. PCH) alimentam CL /c /w3 /Yu $(BOUNDRY) applib.cpp, que produz applib.obj. myapp.cpp, $(UNSTABLEHDR) e $(STABLE. PCH) alimentam CL /c /w3 /Yu $(BOUNDRY) myapp.cpp, que produz myapp.obj. Finalmente, applib.obj e myapp.obj são combinados por LINK /NOD ONERROR:NOEXE $(OBJS), myapp, NUL, $(LIBS), NUL para produzir myapp.exe.

Começando na parte superior do diagrama, ambas STABLEHDRS e BOUNDRY são macros NMAKE nas quais você lista arquivos que provavelmente não precisarão de recompilação. Esses arquivos são compilados pela cadeia de comando

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

somente se o arquivo de cabeçalho pré-compilado (STABLE.pch) não existir ou se você fizer alterações nos arquivos listados nas duas macros. Em ambos os casos, o arquivo de cabeçalho pré-compilado conterá código somente dos arquivos listados na STABLEHDRS macro. Liste o último ficheiro que pretende pré-compilar na macro BOUNDRY.

Os arquivos listados nessas macros podem ser arquivos de cabeçalho ou arquivos de origem C ou C++. (Um único arquivo PCH não pode ser usado com fontes C e C++.) Você pode usar a macro para parar a hdrstop pré-compilação em algum ponto dentro do BOUNDRY arquivo. Para obter mais informações, consulte hdrstop.

Em seguida, no diagrama, APPLIB.obj representa o código de suporte usado em sua aplicação final. É criado a partir de APPLIB.cpp, dos arquivos listados na macro UNSTABLEHDRS e do código pré-compilado do cabeçalho pré-compilado.

MYAPP.obj representa a sua candidatura final. É criado a partir de MYAPP.cpp, dos arquivos listados na macro UNSTABLEHDRS e do código pré-compilado do cabeçalho pré-compilado.

Finalmente, o arquivo executável (MYAPP.EXE) é criado vinculando os arquivos listados na OBJS macro (APPLIB.obj e MYAPP.obj).

Exemplo de makefile para PCH

O Makefile a seguir usa macros e uma estrutura de comando de fluxo de controle com !IF, !ELSE, !ENDIF para simplificar a sua adaptação ao projeto.

# 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

Além dos STABLEHDRS, BOUNDRY e UNSTABLEHDRS macros mostradas na figura "Estrutura de um makefile que usa um ficheiro de cabeçalho pré-compilado" em ficheiros PCH no processo de compilação, este makefile fornece um CLFLAGS macro e um LINKFLAGS macro. Você deve usar essas macros para listar as opções do compilador e do ligador que se aplicam quer você crie uma versão de depuração ou final do arquivo executável da aplicação. Há também uma LIBS macro onde você lista as bibliotecas que seu projeto requer.

O makefile também usa !IF, !ELSE, !ENDIF para detetar se você define um DEBUG símbolo na linha de comando NMAKE:

NMAKE DEBUG=[1|0]

Este recurso possibilita que você use o mesmo makefile durante o desenvolvimento e para as versões finais do seu programa. Use DEBUG=0 para as versões finais. As seguintes linhas de comando são equivalentes:

NMAKE
NMAKE DEBUG=0

Para obter mais informações sobre makefiles, consulte Referência NMAKE. Consulte também as opções do compilador MSVC e as opções do vinculador MSVC.

Código de exemplo para PCH

Os seguintes arquivos de origem são usados no makefile descrito em arquivos PCH no processo de compilação e makefile de exemplo para PCH. Os comentários contêm informações importantes.

Ficheiro de origem ANOTHER.H

// 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

Ficheiro de origem STABLE.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

Ficheiro de origem UNSTABLE.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

Ficheiro de origem APPLIB.CPP

// 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";
    }

Ficheiro de origem MYAPP.CPP

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

Ver também

Comparar unidades de cabeçalho, módulos e cabeçalhos pré-compilados
Referência de Construção de C/C++
opções do compilador MSVC
Visão geral dos módulos em C++
Tutorial: Importar a biblioteca padrão C++ usando módulos
Passo a passo: Criar e importar unidades de cabeçalho em seus projetos do Visual C++
Passo a passo: Importar bibliotecas STL como unidades de cabeçalho