Archivos de encabezado precompilado

Al crear un nuevo proyecto en Visual Studio, se agrega un archivo de encabezado precompilado denominado pch.h al proyecto. (En Visual Studio 2017 y versiones anteriores, el archivo se llamó stdafx.h.) El propósito del archivo es acelerar el proceso de compilación. Aquí se deben incluir los archivos de encabezado estables, por ejemplo, los encabezados de la biblioteca estándar, como <vector>. El encabezado precompilado solo se compila cuando se modifica el archivo o los archivos que incluye. Si solo realiza cambios en el código fuente del proyecto, se omitirá la compilación del encabezado precompilado.

Las opciones del compilador para los encabezados precompilados son /Y. En las páginas de propiedades del proyecto, las opciones se encuentran en Propiedades de configuración>C/C++>Encabezados precompilados. Puede optar por no usar encabezados precompilados, y puede especificar el nombre del archivo de encabezado y el nombre y la ruta de acceso del archivo de salida.

Código precompilado personalizado

En el caso de proyectos grandes que tardan mucho tiempo en compilarse, puede que quiera plantearse la creación de archivos precompilados personalizados. Los compiladores de Microsoft C y C++ ofrecen opciones para precompilar cualquier código de C o C++, incluido el código en línea. Usar esta función de rendimiento le permite compilar un cuerpo estable de código, almacenar el estado compilado del código en un archivo y, en las posteriores compilaciones, combinar el código precompilado con código que todavía se esté desarrollando. Cada compilación posterior se realizará más rápido porque no se tendrá que volver a compilar el código estable.

Cuándo precompilar código fuente

El código precompilado es útil durante el ciclo de desarrollo para reducir el tiempo de compilación, sobre todo si:

  • Siempre usa un gran bloque de código que cambia con poca frecuencia.

  • Su programa consta de varios módulos y todos usan un conjunto estándar de archivos de inclusión y las mismas opciones de compilación. En este caso, todos los archivos de inclusión se pueden precompilar en un encabezado precompilado. Para obtener más información sobre las formas más recientes de controlar archivos de inclusión, vea Comparar unidades de encabezado, módulos y encabezados precompilados.

La primera compilación (la que crea el archivo de encabezado precompilado) tarda un poco más que las compilaciones posteriores. Las compilaciones posteriores pueden realizarse con mayor rapidez si se incluye el código precompilado.

Puede precompilar tanto programas de C como de C++. En la programación de C++, una práctica común es separar la información de la interfaz de clase en archivos de encabezado. Estos archivos de encabezado pueden incluirse posteriormente en los programas que usan la clase. Al precompilar estos encabezados, puede reducir el tiempo de compilación de los programas.

Nota:

Aunque solo puede usar un archivo de encabezado precompilado (.pch) por cada archivo de código fuente, puede usar varios archivos .pch en un proyecto.

Dos opciones para precompilar código

Puede precompilar cualquier código de C o C++; no solo archivos de encabezado.

La precompilación requiere planeación, pero ofrece compilaciones mucho más rápidas si precompila código fuente que no sea solo de archivos de encabezado sencillos.

Precompile el código cuando sepa que sus archivos de código fuente usan conjuntos comunes de archivos de encabezado, o cuando quiera incluir código fuente en la precompilación.

Las opciones de encabezado precompilado son /Yc (Crear archivo de encabezado precompilado) y /Yu (Usar archivo de encabezado precompilado). Use /Yc para crear un encabezado precompilado. Cuando se usa con la pragma opcional hdrstop , /Yc permite precompilar los archivos de encabezado y el código fuente. Seleccione /Yu esta opción para usar un encabezado precompilado existente en la compilación existente. También puede usar /Fp con las /Yc opciones y /Yu para proporcionar un nombre alternativo para el encabezado precompilado.

En los artículos de referencia de las opciones del compilador para /Yu y /Yc se describe cómo acceder a esta funcionalidad en el entorno de desarrollo.

Reglas de coherencia de los encabezados precompilados

Como los archivos PCH contienen información sobre el entorno de la máquina y sobre la dirección de memoria del programa, solo debe usar un archivo PCH en la máquina en la que se creó.

Reglas de coherencia para el uso de encabezados precompilados por cada archivo

La /Yu opción del compilador permite especificar qué archivo PCH se va a usar.

Cuando usa un archivo PCH, el compilador adopta el mismo entorno de compilación que estaba activo al crear el archivo PCH, a menos que se especifique lo contrario. El entorno de compilación incluye las opciones del compilador, pragmas, etc. Si el compilador detecta una incoherencia, emite una advertencia e identifica la incoherencia siempre que sea posible. Estas advertencias no indican necesariamente un problema con el archivo PCH, simplemente le avisan de posibles conflictos. En las secciones siguientes se describen los requisitos de coherencia de los archivos PCH.

Coherencia de las opciones del compilador

Las siguientes opciones del compilador pueden desencadenar una advertencia de incoherencia cuando se usa un archivo PCH:

  • Las macros creadas mediante la opción de preprocesador (/D) deben ser las mismas entre la compilación que creó el archivo PCH y la compilación actual. No se comprueba el estado de las constantes definidas, pero se pueden producir resultados imprevistos si las macros cambian.

  • Los archivos PCH no funcionan con las opciones /E y /EP.

  • Los archivos PCH se deben crearse con la opción Generate Browse Info (Generar información del explorador) (/FR) o la opción Exclude Local Variables (Excluir variables locales) (/Fr) antes de que las compilaciones posteriores que usan el archivo PCH puedan usar estas opciones.

Compatible con C 7.0 (/Z7)

Si esta opción está activada cuando se crea el archivo PCH, las compilaciones posteriores que usen el archivo PCH podrán usar la información de depuración.

Si la opción Compatible con C 7.0 (/Z7) no está activada cuando se crea el archivo PCH, las compilaciones posteriores que usen el archivo PCH y /Z7 desencadenarán una advertencia. La información de depuración se coloca en el archivo .obj actual y los símbolos locales definidos en el archivo PCH no están disponibles para el depurador.

Coherencia de la ruta de acceso de inclusión

Un archivo PCH no contiene información sobre la ruta de acceso de inclusión de encabezado que estaba establecida cuando se creó. A la hora de usar un archivo PCH, el compilador siempre usa la ruta de acceso de inclusión de encabezado especificada en la compilación actual.

Coherencia del archivo de código fuente

Cuando se especifica la opción Use Precompiled Header File (Usar el archivo de encabezado precompilado) (/Yu), el compilador omite todas las directivas de preprocesador (incluidas las pragmas) que aparecen en el código fuente que se precompilará. La compilación especificada por estas directivas de preprocesador debe ser la misma que la usada para la opción Create Precompiled Header File (Crear un archivo de encabezado precompilado) (/Yc).

Coherencia de las pragmas

Las pragmas procesadas durante la creación de un archivo PCH suelen afectar al archivo con el que se usa posteriormente el archivo PCH. Las pragmas comment y message no afectan al resto de la compilación.

Estas pragmas solo afectan al código del archivo PCH y no al código que usará este archivo más tarde:

comment
linesize

message
page

pagesize
skip

subtitle
title

Estas pragmas se conservan como parte de un encabezado precompilado y afectan al resto de una compilación que usa el encabezado precompilado:

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

Reglas de coherencia para /Yc e /Yu

Cuando se usa un encabezado precompilado creado con /Yc o /Yu, el compilador compara el entorno de compilación actual con el que existía cuando se creó el archivo PCH. Asegúrese de especificar un entorno coherente con el anterior (use opciones de compilador coherentes, pragmas, etc.) para la compilación actual. Si el compilador detecta una incoherencia, emite una advertencia e identifica la incoherencia siempre que sea posible. Estas advertencias no indican necesariamente un problema con el archivo PCH, simplemente le avisan de posibles conflictos. En las siguientes secciones se explican los requisitos de coherencia de los encabezados precompilados.

Coherencia de las opciones del compilador

En esta tabla se enumeran las opciones del compilador que pueden desencadenar una advertencia de incoherencia cuando se usa un encabezado precompilado:

Opción Nombre Regla
/D Definir constantes y macros Deben ser las mismas entre la compilación que creó el encabezado precompilado y la compilación actual. No se comprueba el estado de las constantes definidas. Pero se pueden producir resultados imprevistos si los archivos dependen de los valores de las constantes modificadas.
/E o /EP Copiar los resultados del preprocesador en una salida estándar Los encabezados precompilados no funcionan con la opción /E o /EP.
/Fr o /FR Generar información del explorador de código fuente de Microsoft Para que las opciones /Fr y /FR sean válidas con la opción /Yu, deben estar también activadas al crear el encabezado precompilado. Las compilaciones posteriores que usan el encabezado precompilado también generan información del explorador de código fuente. La información del explorador se coloca en un único archivo .sbr y otros archivos le hacen referencia como a la información de CodeView. No se puede invalidar la colocación de la información del Explorador de código fuente.
/GA, /GD, /GE, /Gw o /GW Opciones de protocolo de Windows Deben ser las mismas entre la compilación que creó el encabezado precompilado y la compilación actual. El compilador emite una advertencia si estas opciones difieren.
/Zi Generar información de depuración completa Si esta opción está activada cuando se crea el encabezado precompilado, las compilaciones posteriores que usen la precompilación podrán usar la información de depuración. Si la opción /Zi no está activada cuando se crea el encabezado precompilado, las compilaciones posteriores que usen la precompilación y la opción /Zi desencadenarán una advertencia. La información de depuración se coloca en el archivo objeto actual y los símbolos locales definidos en el encabezado precompilado no están disponibles para el depurador.

Nota:

La utilidad del encabezado precompilado está pensada para usarse solo en archivos de código fuente de C y C++.

Uso de encabezados precompilados en un proyecto

En las secciones anteriores se presenta información general sobre los encabezados precompilados: /Yc y /Yu, la opción /Fp y la pragma hdrstop. En esta sección se describe un método para usar las opciones de encabezado precompilado manual en un proyecto; la sección finaliza con un archivo Make de ejemplo y con el código que administra.

Para obtener otro enfoque sobre el uso de las opciones de encabezado precompilado manual en un proyecto, analice uno de los archivos Make que se encuentran en el directorio MFC\SRC que se crea durante la instalación predeterminada de Visual Studio. Estos archivos Make adoptan un enfoque similar al que se presenta en esta sección. Hacen mejor uso de las macros de Microsoft Program Maintenance Utility (Utilidad de mantenimiento del programa de Microsoft) (NMAKE), y ofrecer un mayor control del proceso de compilación.

Archivos PCH en el proceso de compilación

El código base de un proyecto de software se suele incluir en varios archivos objeto, bibliotecas, archivos de encabezado y archivos de código fuente de C o C++. Normalmente, un archivo Make coordina la combinación de estos elementos en un archivo ejecutable. La siguiente ilustración muestra la estructura de un archivo Make que usa un archivo de encabezado precompilado. Los nombres de macro NMAKE y los nombres de archivo de este diagrama son coherentes con los del código de ejemplo que se encuentra en las secciones Archivo Make de ejemplo para PCH y Código de ejemplo para PCH.

En la ilustración se usan tres dispositivos en diagramas para mostrar el flujo del proceso de compilación. Los rectángulos con nombre representan cada archivo o macro; las tres macros representan uno o varios archivos. Las áreas sombreadas representan cada acción de compilación o vinculación. Las flechas muestran qué archivos y macros se combinan durante el proceso de compilación o vinculación.

 The diagram is described in the text following the diagram.
Estructura de un archivo Make que usa un archivo de encabezado precompilado:

Diagram showing example inputs and outputs of a makefile that uses a precompiled header file.

El diagrama muestra "$(STABLEHDRS)" y "$(BOUNDRY)" que se alimenta en CL /c /W3 /Yc$(BOUNDRY) applib.cpp myapp.cpp. La salida de ese valor es $(STABLE. PCH). A continuación, applib.cpp y $(UNSTABLEHDRS) y $(STABLE. PCH) se introduce en CL /c /w3 /Yu $(BOUNDRY) applib.cpp, que genera applib.obj. myapp.cpp, $(UNSTABLEHDR) y $(STABLE. PCH) se introduce en CL /c /w3 /Yu $(BOUNDRY) myapp.cpp, que genera myapp.obj. Por último, applib.obj y myapp.obj se combinan mediante LINK /NOD ONERROR:NOEXE $(OBJS), myapp, NUL, $(LIBS), NUL para producir myapp.exe.

En la parte superior del diagrama, tanto STABLEHDRS como BOUNDRY son macros NMAKE en las que se enumeran los archivos que no es probable que necesiten volver a compilarse. Estos archivos se compilan mediante la cadena de comandos

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

solo si el archivo de encabezado precompilado (STABLE.pch) no existe o si se realizan cambios en los archivos que figuran en las dos macros. En cualquier caso, el archivo de encabezado precompilado solo contendrá código de los archivos del macro STABLEHDRS. Enumere el último archivo que quiere precompilar en la macro BOUNDRY.

Los archivos que se enumeran en estas macros pueden ser archivos de encabezado o archivos de código fuente de C o C++. (No se puede usar un único archivo PCH con orígenes de C y C++). Puede usar la macro hdrstop para detener la precompilación en algún momento en el archivo BOUNDRY. Para obtener más información, vea hdrstop.

Lo siguiente en el diagrama, APPLIB.obj representa el código de soporte que se usa en la aplicación final. Se crea a partir de APPLIB.cpp, los archivos enumerados en la macro UNSTABLEHDRS y el código precompilado del encabezado precompilado.

MYAPP.obj representa la aplicación final. Se crea a partir de MYAPP.cpp, los archivos enumerados en la macro UNSTABLEHDRS y el código precompilado del encabezado precompilado.

Por último, se crea el archivo ejecutable (MYAPP.EXE) al vincular los archivos enumerados en la macro OBJS (APPLIB.obj y MYAPP.obj).

Archivo Make de ejemplo para PCH

El siguiente archivo Make usa macros y una estructura de comandos de flujo de control !IF, !ELSE, !ENDIF para simplificar su adaptación al proyecto.

# 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

Además de las macros STABLEHDRS, BOUNDRY y UNSTABLEHDRS que se muestran en la ilustración "Estructura de un archivo Make que usa un archivo de encabezado precompilado" en la sección Archivos PCH en el proceso de compilación, este archivo Make proporciona una macro CLFLAGS y una macro LINKFLAGS. Debe usar estas macros para enumerar las opciones del compilador y del enlazador que se aplican si se compila una versión de depuración o una versión final del archivo ejecutable de la aplicación. También hay una macro LIBS en la que se enumeran las bibliotecas que requiere el proyecto.

El archivo Make también usa !IF, !ELSE, !ENDIF para detectar si ha definido un símbolo DEBUG en la línea de comandos de NMAKE:

NMAKE DEBUG=[1|0]

Esta característica permite usar el mismo archivo Make durante el desarrollo y para las versiones finales del programa. Use DEBUG=0 para las versiones finales. Las siguientes líneas de comandos son equivalentes:

NMAKE
NMAKE DEBUG=0

Para más información sobre los archivos Make, vea Referencia de NMAKE. Consulte también los artículos Opciones del compilador de MSVC y Opciones del enlazador MSVC.

Código de ejemplo para PCH

Los siguientes archivos de código fuente se usan en el archivo Make descrito en las secciones Archivos PCH en el proceso de compilación y Archivo Make de ejemplo para PCH. Los comentarios contienen información importante.

Archivo de origen 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

Archivo de origen 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

Archivo de origen 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

Archivo de origen 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";
    }

Archivo de origen 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();
}

Consulte también

Comparación de unidades de encabezado, módulos y encabezados precompilados
Referencia de compilación de C/C++
Opcionesdel compilador de MSVC Introducción a los módulos en C++
Tutorial: Importación de la biblioteca estándar de C++ mediante módulos
Tutorial: Compilación e importación de unidades de encabezado en proyectos de Visual C++
Tutorial: Importación de bibliotecas STL como unidades de encabezado